-/* \r
+/*\r
* WinBoard.c -- Windows NT front end to XBoard\r
- * $Id$\r
*\r
- * Copyright 1991 by Digital Equipment Corporation, Maynard, Massachusetts.\r
- * Enhancements Copyright 1992-2001 Free Software Foundation, Inc.\r
+ * Copyright 1991 by Digital Equipment Corporation, Maynard,\r
+ * Massachusetts.\r
+ *\r
+ * Enhancements Copyright 1992-2001, 2002, 2003, 2004, 2005, 2006,\r
+ * 2007, 2008, 2009 Free Software Foundation, Inc.\r
+ *\r
+ * Enhancements Copyright 2005 Alessandro Scotti\r
*\r
* XBoard borrows its colors and the bitmaps.xchess bitmap set from XChess,\r
* which was written and is copyrighted by Wayne Christopher.\r
* SOFTWARE.\r
* ------------------------------------------------------------------------\r
*\r
- * The following terms apply to the enhanced version of XBoard distributed\r
- * by the Free Software Foundation:\r
+ * The following terms apply to the enhanced version of XBoard\r
+ * distributed by the Free Software Foundation:\r
* ------------------------------------------------------------------------\r
- * This program is free software; you can redistribute it and/or modify\r
+ *\r
+ * GNU XBoard is free software: you can redistribute it and/or modify\r
* it under the terms of the GNU General Public License as published by\r
- * the Free Software Foundation; either version 2 of the License, or\r
- * (at your option) any later version.\r
+ * the Free Software Foundation, either version 3 of the License, or (at\r
+ * your option) any later version.\r
*\r
- * This program is distributed in the hope that it will be useful,\r
- * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r
- * GNU General Public License for more details.\r
+ * GNU XBoard is distributed in the hope that it will be useful, but\r
+ * WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU\r
+ * General Public License for more details.\r
*\r
* You should have received a copy of the GNU General Public License\r
- * along with this program; if not, write to the Free Software\r
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.\r
- * ------------------------------------------------------------------------\r
- */\r
+ * along with this program. If not, see http://www.gnu.org/licenses/. *\r
+ *\r
+ *------------------------------------------------------------------------\r
+ ** See the file ChangeLog for a revision history. */\r
\r
#include "config.h"\r
\r
#include <windows.h>\r
#include <winuser.h>\r
#include <winsock.h>\r
+#include <commctrl.h>\r
\r
#include <stdio.h>\r
#include <stdlib.h>\r
+#include <time.h>\r
#include <malloc.h>\r
#include <sys/stat.h>\r
#include <fcntl.h>\r
#include <dlgs.h>\r
#include <richedit.h>\r
#include <mmsystem.h>\r
+#include <ctype.h>\r
\r
#if __GNUC__\r
#include <errno.h>\r
#include "woptions.h"\r
#include "wsockerr.h"\r
#include "defaults.h"\r
-\r
+#include "help.h"\r
+#include "wsnap.h"\r
+\r
+//void InitEngineUCI( const char * iniDir, ChessProgramState * cps );\r
+\r
+ int myrandom(void);\r
+ void mysrandom(unsigned int seed);\r
+\r
+extern int whiteFlag, blackFlag;\r
+Boolean flipClock = FALSE;\r
+extern HANDLE chatHandle[];\r
+extern int ics_type;\r
+\r
+void DisplayHoldingsCount(HDC hdc, int x, int y, int align, int copyNumber);\r
+VOID NewVariantPopup(HWND hwnd);\r
+int FinishMove P((ChessMove moveType, int fromX, int fromY, int toX, int toY,\r
+ /*char*/int promoChar));\r
+void AnimateAtomicCapture(int fromX, int fromY, int toX, int toY, int nFrames);\r
+void DisplayMove P((int moveNumber));\r
+Boolean ParseFEN P((Board board, int *blackPlaysFirst, char *fen));\r
+void ChatPopUp P(());\r
typedef struct {\r
- ChessSquare piece; \r
+ ChessSquare piece;\r
POINT pos; /* window coordinates of current pos */\r
POINT lastpos; /* window coordinates of last pos - used for clipping */\r
POINT from; /* board coordinates of the piece's orig pos */\r
static DragInfo dragInfo = { {-1,-1}, {-1,-1}, {-1,-1}, {-1,-1} };\r
\r
typedef struct {\r
- POINT sq[2]; /* board coordinates of from, to squares */\r
+ POINT sq[2]; /* board coordinates of from, to squares */\r
} HighlightInfo;\r
\r
static HighlightInfo highlightInfo = { {{-1, -1}, {-1, -1}} };\r
static HighlightInfo premoveHighlightInfo = { {{-1, -1}, {-1, -1}} };\r
\r
+typedef struct { // [HGM] atomic\r
+ int fromX, fromY, toX, toY, radius;\r
+} ExplodeInfo;\r
+\r
+static ExplodeInfo explodeInfo;\r
+\r
/* Window class names */\r
char szAppName[] = "WinBoard";\r
char szConsoleName[] = "WBConsole";\r
\r
/* Title bar text */\r
char szTitle[] = "WinBoard";\r
-char szConsoleTitle[] = "ICS Interaction";\r
+char szConsoleTitle[] = "I C S Interaction";\r
\r
char *programName;\r
char *settingsFileName;\r
\r
BoardSize boardSize;\r
BOOLEAN chessProgram;\r
-static int boardX, boardY, consoleX, consoleY, consoleW, consoleH;\r
-static int squareSize, lineGap;\r
-static int winWidth, winHeight;\r
-static RECT messageRect, whiteRect, blackRect;\r
+static int boardX, boardY;\r
+int minX, minY; // [HGM] placement: volatile limits on upper-left corner\r
+static int squareSize, lineGap, minorSize;\r
+static int winWidth, winHeight, winW, winH;\r
+static RECT messageRect, whiteRect, blackRect, leftLogoRect, rightLogoRect; // [HGM] logo\r
+static int logoHeight = 0;\r
static char messageText[MESSAGE_TEXT_MAX];\r
static int clockTimerEvent = 0;\r
static int loadGameTimerEvent = 0;\r
char *firstChessProgramNames;\r
char *secondChessProgramNames;\r
\r
-#define ARG_MAX 20000\r
+#define ARG_MAX 128*1024 /* [AS] For Roger Brown's very long list! */\r
\r
#define PALETTESIZE 256\r
\r
HWND hwndConsole = NULL;\r
BOOLEAN alwaysOnTop = FALSE;\r
RECT boardRect;\r
-COLORREF lightSquareColor, darkSquareColor, whitePieceColor, \r
+COLORREF lightSquareColor, darkSquareColor, whitePieceColor,\r
blackPieceColor, highlightSquareColor, premoveHighlightColor;\r
HPALETTE hPal;\r
ColorClass currentColorClass;\r
\r
HWND hCommPort = NULL; /* currently open comm port */\r
static HWND hwndPause; /* pause button */\r
-static HBITMAP pieceBitmap[3][(int) WhiteKing + 1];\r
+static HBITMAP pieceBitmap[3][(int) BlackPawn]; /* [HGM] nr of bitmaps referred to bP in stead of wK */\r
static HBRUSH lightSquareBrush, darkSquareBrush,\r
- whitePieceBrush, blackPieceBrush, iconBkgndBrush, outlineBrush;\r
+ blackSquareBrush, /* [HGM] for band between board and holdings */\r
+ explodeBrush, /* [HGM] atomic */\r
+ whitePieceBrush, blackPieceBrush, iconBkgndBrush /*, outlineBrush*/;\r
static POINT gridEndpoints[(BOARD_SIZE + 1) * 4];\r
static DWORD gridVertexCounts[(BOARD_SIZE + 1) * 2];\r
static HPEN gridPen = NULL;\r
static int doingSizing = FALSE;\r
static int lastSizing = 0;\r
static int prevStderrPort;\r
+static HBITMAP userLogo;\r
+\r
+/* [AS] Support for background textures */\r
+#define BACK_TEXTURE_MODE_DISABLED 0\r
+#define BACK_TEXTURE_MODE_PLAIN 1\r
+#define BACK_TEXTURE_MODE_FULL_RANDOM 2\r
+\r
+static HBITMAP liteBackTexture = NULL;\r
+static HBITMAP darkBackTexture = NULL;\r
+static int liteBackTextureMode = BACK_TEXTURE_MODE_PLAIN;\r
+static int darkBackTextureMode = BACK_TEXTURE_MODE_PLAIN;\r
+static int backTextureSquareSize = 0;\r
+static struct { int x; int y; int mode; } backTextureSquareInfo[BOARD_SIZE][BOARD_SIZE];\r
\r
#if __GNUC__ && !defined(_winmajor)\r
#define oldDialog 0 /* cygwin doesn't define _winmajor; mingw does */\r
#else\r
+#if defined(_winmajor)\r
#define oldDialog (_winmajor < 4)\r
+#else\r
+#define oldDialog 0\r
+#endif\r
#endif\r
\r
-char *defaultTextAttribs[] = \r
+char *defaultTextAttribs[] =\r
{\r
COLOR_SHOUT, COLOR_SSHOUT, COLOR_CHANNEL1, COLOR_CHANNEL, COLOR_KIBITZ,\r
COLOR_TELL, COLOR_CHALLENGE, COLOR_REQUEST, COLOR_SEEK, COLOR_NORMAL,\r
int cliWidth, cliHeight;\r
} SizeInfo;\r
\r
-SizeInfo sizeInfo[] = \r
+SizeInfo sizeInfo[] =\r
{\r
{ "tiny", 21, 0, 1, 1, 0, 0 },\r
{ "teeny", 25, 1, 1, 1, 0, 0 },\r
{ NULL, 0, 0, 0, 0, 0, 0 }\r
};\r
\r
-#define MF(x) {x, {0, }, {0, }, 0}\r
+#define MF(x) {x, {{0,}, 0. }, {0, }, 0}\r
MyFont fontRec[NUM_SIZES][NUM_FONTS] =\r
{\r
- { MF(CLOCK_FONT_TINY), MF(MESSAGE_FONT_TINY), \r
- MF(COORD_FONT_TINY), MF(CONSOLE_FONT_TINY),\r
- MF(COMMENT_FONT_TINY), MF(EDITTAGS_FONT_TINY) },\r
- { MF(CLOCK_FONT_TEENY), MF(MESSAGE_FONT_TEENY), \r
- MF(COORD_FONT_TEENY), MF(CONSOLE_FONT_TEENY),\r
- MF(COMMENT_FONT_TEENY), MF(EDITTAGS_FONT_TEENY) },\r
- { MF(CLOCK_FONT_DINKY), MF(MESSAGE_FONT_DINKY),\r
- MF(COORD_FONT_DINKY), MF(CONSOLE_FONT_DINKY),\r
- MF(COMMENT_FONT_DINKY), MF(EDITTAGS_FONT_DINKY) },\r
- { MF(CLOCK_FONT_PETITE), MF(MESSAGE_FONT_PETITE),\r
- MF(COORD_FONT_PETITE), MF(CONSOLE_FONT_PETITE),\r
- MF(COMMENT_FONT_PETITE), MF(EDITTAGS_FONT_PETITE) },\r
- { MF(CLOCK_FONT_SLIM), MF(MESSAGE_FONT_SLIM),\r
- MF(COORD_FONT_SLIM), MF(CONSOLE_FONT_SLIM),\r
- MF(COMMENT_FONT_SLIM), MF(EDITTAGS_FONT_SLIM) },\r
- { MF(CLOCK_FONT_SMALL), MF(MESSAGE_FONT_SMALL),\r
- MF(COORD_FONT_SMALL), MF(CONSOLE_FONT_SMALL),\r
- MF(COMMENT_FONT_SMALL), MF(EDITTAGS_FONT_SMALL) },\r
- { MF(CLOCK_FONT_MEDIOCRE), MF(MESSAGE_FONT_MEDIOCRE),\r
- MF(COORD_FONT_MEDIOCRE), MF(CONSOLE_FONT_MEDIOCRE),\r
- MF(COMMENT_FONT_MEDIOCRE), MF(EDITTAGS_FONT_MEDIOCRE) },\r
- { MF(CLOCK_FONT_MIDDLING), MF(MESSAGE_FONT_MIDDLING),\r
- MF(COORD_FONT_MIDDLING), MF(CONSOLE_FONT_MIDDLING),\r
- MF(COMMENT_FONT_MIDDLING), MF(EDITTAGS_FONT_MIDDLING) },\r
- { MF(CLOCK_FONT_AVERAGE), MF(MESSAGE_FONT_AVERAGE),\r
- MF(COORD_FONT_AVERAGE), MF(CONSOLE_FONT_AVERAGE),\r
- MF(COMMENT_FONT_AVERAGE), MF(EDITTAGS_FONT_AVERAGE) },\r
- { MF(CLOCK_FONT_MODERATE), MF(MESSAGE_FONT_MODERATE),\r
- MF(COORD_FONT_MODERATE), MF(CONSOLE_FONT_MODERATE),\r
- MF(COMMENT_FONT_MODERATE), MF(EDITTAGS_FONT_MODERATE) },\r
- { MF(CLOCK_FONT_MEDIUM), MF(MESSAGE_FONT_MEDIUM),\r
- MF(COORD_FONT_MEDIUM), MF(CONSOLE_FONT_MEDIUM),\r
- MF(COMMENT_FONT_MEDIUM), MF(EDITTAGS_FONT_MEDIUM) },\r
- { MF(CLOCK_FONT_BULKY), MF(MESSAGE_FONT_BULKY),\r
- MF(COORD_FONT_BULKY), MF(CONSOLE_FONT_BULKY),\r
- MF(COMMENT_FONT_BULKY), MF(EDITTAGS_FONT_BULKY) },\r
- { MF(CLOCK_FONT_LARGE), MF(MESSAGE_FONT_LARGE),\r
- MF(COORD_FONT_LARGE), MF(CONSOLE_FONT_LARGE),\r
- MF(COMMENT_FONT_LARGE), MF(EDITTAGS_FONT_LARGE) },\r
- { MF(CLOCK_FONT_BIG), MF(MESSAGE_FONT_BIG),\r
- MF(COORD_FONT_BIG), MF(CONSOLE_FONT_BIG),\r
- MF(COMMENT_FONT_BIG), MF(EDITTAGS_FONT_BIG) },\r
- { MF(CLOCK_FONT_HUGE), MF(MESSAGE_FONT_HUGE),\r
- MF(COORD_FONT_HUGE), MF(CONSOLE_FONT_HUGE),\r
- MF(COMMENT_FONT_HUGE), MF(EDITTAGS_FONT_HUGE) },\r
- { MF(CLOCK_FONT_GIANT), MF(MESSAGE_FONT_GIANT),\r
- MF(COORD_FONT_GIANT), MF(CONSOLE_FONT_GIANT),\r
- MF(COMMENT_FONT_GIANT), MF(EDITTAGS_FONT_GIANT) },\r
- { MF(CLOCK_FONT_COLOSSAL), MF(MESSAGE_FONT_COLOSSAL),\r
- MF(COORD_FONT_COLOSSAL), MF(CONSOLE_FONT_COLOSSAL),\r
- MF(COMMENT_FONT_COLOSSAL), MF(EDITTAGS_FONT_COLOSSAL) },\r
- { MF(CLOCK_FONT_TITANIC), MF(MESSAGE_FONT_TITANIC),\r
- MF(COORD_FONT_TITANIC), MF(CONSOLE_FONT_TITANIC),\r
- MF(COMMENT_FONT_TITANIC), MF(EDITTAGS_FONT_TITANIC) },\r
+ { MF(CLOCK_FONT_TINY), MF(MESSAGE_FONT_TINY), MF(COORD_FONT_TINY), MF(CONSOLE_FONT_TINY), MF(COMMENT_FONT_TINY), MF(EDITTAGS_FONT_TINY), MF(MOVEHISTORY_FONT_ALL) },\r
+ { MF(CLOCK_FONT_TEENY), MF(MESSAGE_FONT_TEENY), MF(COORD_FONT_TEENY), MF(CONSOLE_FONT_TEENY), MF(COMMENT_FONT_TEENY), MF(EDITTAGS_FONT_TEENY), MF(MOVEHISTORY_FONT_ALL) },\r
+ { MF(CLOCK_FONT_DINKY), MF(MESSAGE_FONT_DINKY), MF(COORD_FONT_DINKY), MF(CONSOLE_FONT_DINKY), MF(COMMENT_FONT_DINKY), MF(EDITTAGS_FONT_DINKY), MF(MOVEHISTORY_FONT_ALL) },\r
+ { MF(CLOCK_FONT_PETITE), MF(MESSAGE_FONT_PETITE), MF(COORD_FONT_PETITE), MF(CONSOLE_FONT_PETITE), MF(COMMENT_FONT_PETITE), MF(EDITTAGS_FONT_PETITE), MF(MOVEHISTORY_FONT_ALL) },\r
+ { MF(CLOCK_FONT_SLIM), MF(MESSAGE_FONT_SLIM), MF(COORD_FONT_SLIM), MF(CONSOLE_FONT_SLIM), MF(COMMENT_FONT_SLIM), MF(EDITTAGS_FONT_SLIM), MF(MOVEHISTORY_FONT_ALL) },\r
+ { MF(CLOCK_FONT_SMALL), MF(MESSAGE_FONT_SMALL), MF(COORD_FONT_SMALL), MF(CONSOLE_FONT_SMALL), MF(COMMENT_FONT_SMALL), MF(EDITTAGS_FONT_SMALL), MF(MOVEHISTORY_FONT_ALL) },\r
+ { MF(CLOCK_FONT_MEDIOCRE), MF(MESSAGE_FONT_MEDIOCRE), MF(COORD_FONT_MEDIOCRE), MF(CONSOLE_FONT_MEDIOCRE), MF(COMMENT_FONT_MEDIOCRE), MF(EDITTAGS_FONT_MEDIOCRE), MF(MOVEHISTORY_FONT_ALL) },\r
+ { MF(CLOCK_FONT_MIDDLING), MF(MESSAGE_FONT_MIDDLING), MF(COORD_FONT_MIDDLING), MF(CONSOLE_FONT_MIDDLING), MF(COMMENT_FONT_MIDDLING), MF(EDITTAGS_FONT_MIDDLING), MF(MOVEHISTORY_FONT_ALL) },\r
+ { MF(CLOCK_FONT_AVERAGE), MF(MESSAGE_FONT_AVERAGE), MF(COORD_FONT_AVERAGE), MF(CONSOLE_FONT_AVERAGE), MF(COMMENT_FONT_AVERAGE), MF(EDITTAGS_FONT_AVERAGE), MF(MOVEHISTORY_FONT_ALL) },\r
+ { MF(CLOCK_FONT_MODERATE), MF(MESSAGE_FONT_MODERATE), MF(COORD_FONT_MODERATE), MF(CONSOLE_FONT_MODERATE), MF(COMMENT_FONT_MODERATE), MF(EDITTAGS_FONT_MODERATE), MF(MOVEHISTORY_FONT_ALL) },\r
+ { MF(CLOCK_FONT_MEDIUM), MF(MESSAGE_FONT_MEDIUM), MF(COORD_FONT_MEDIUM), MF(CONSOLE_FONT_MEDIUM), MF(COMMENT_FONT_MEDIUM), MF(EDITTAGS_FONT_MEDIUM), MF(MOVEHISTORY_FONT_ALL) },\r
+ { MF(CLOCK_FONT_BULKY), MF(MESSAGE_FONT_BULKY), MF(COORD_FONT_BULKY), MF(CONSOLE_FONT_BULKY), MF(COMMENT_FONT_BULKY), MF(EDITTAGS_FONT_BULKY), MF(MOVEHISTORY_FONT_ALL) },\r
+ { MF(CLOCK_FONT_LARGE), MF(MESSAGE_FONT_LARGE), MF(COORD_FONT_LARGE), MF(CONSOLE_FONT_LARGE), MF(COMMENT_FONT_LARGE), MF(EDITTAGS_FONT_LARGE), MF(MOVEHISTORY_FONT_ALL) },\r
+ { MF(CLOCK_FONT_BIG), MF(MESSAGE_FONT_BIG), MF(COORD_FONT_BIG), MF(CONSOLE_FONT_BIG), MF(COMMENT_FONT_BIG), MF(EDITTAGS_FONT_BIG), MF(MOVEHISTORY_FONT_ALL) },\r
+ { MF(CLOCK_FONT_HUGE), MF(MESSAGE_FONT_HUGE), MF(COORD_FONT_HUGE), MF(CONSOLE_FONT_HUGE), MF(COMMENT_FONT_HUGE), MF(EDITTAGS_FONT_HUGE), MF(MOVEHISTORY_FONT_ALL) },\r
+ { MF(CLOCK_FONT_GIANT), MF(MESSAGE_FONT_GIANT), MF(COORD_FONT_GIANT), MF(CONSOLE_FONT_GIANT), MF(COMMENT_FONT_GIANT), MF(EDITTAGS_FONT_GIANT), MF(MOVEHISTORY_FONT_ALL) },\r
+ { MF(CLOCK_FONT_COLOSSAL), MF(MESSAGE_FONT_COLOSSAL), MF(COORD_FONT_COLOSSAL), MF(CONSOLE_FONT_COLOSSAL), MF(COMMENT_FONT_COLOSSAL), MF(EDITTAGS_FONT_COLOSSAL), MF(MOVEHISTORY_FONT_ALL) },\r
+ { MF(CLOCK_FONT_TITANIC), MF(MESSAGE_FONT_TITANIC), MF(COORD_FONT_TITANIC), MF(CONSOLE_FONT_TITANIC), MF(COMMENT_FONT_TITANIC), MF(EDITTAGS_FONT_TITANIC), MF(MOVEHISTORY_FONT_ALL) },\r
};\r
\r
MyFont *font[NUM_SIZES][NUM_FONTS];\r
};\r
\r
int tinyLayout = 0, smallLayout = 0;\r
-#define MENU_BAR_ITEMS 6\r
+#define MENU_BAR_ITEMS 7\r
char *menuBarText[2][MENU_BAR_ITEMS+1] = {\r
{ "&File", "&Mode", "&Action", "&Step", "&Options", "&Help", NULL },\r
{ "&F", "&M", "&A", "&S", "&O", "&H", NULL },\r
VOID APIENTRY MenuPopup(HWND hwnd, POINT pt, HMENU hmenu, UINT def);\r
void ParseIcsTextMenu(char *icsTextMenuString);\r
VOID PopUpMoveDialog(char firstchar);\r
+VOID PopUpNameDialog(char firstchar);\r
VOID UpdateSampleText(HWND hDlg, int id, MyColorizeAttribs *mca);\r
\r
+/* [AS] */\r
+int NewGameFRC();\r
+int GameListOptions();\r
+\r
+HWND moveHistoryDialog = NULL;\r
+BOOLEAN moveHistoryDialogUp = FALSE;\r
+\r
+WindowPlacement wpMoveHistory;\r
+\r
+HWND evalGraphDialog = NULL;\r
+BOOLEAN evalGraphDialogUp = FALSE;\r
+\r
+WindowPlacement wpEvalGraph;\r
+\r
+HWND engineOutputDialog = NULL;\r
+BOOLEAN engineOutputDialogUp = FALSE;\r
+\r
+WindowPlacement wpEngineOutput;\r
+WindowPlacement wpGameList;\r
+WindowPlacement wpConsole;\r
+\r
+VOID MoveHistoryPopUp();\r
+VOID MoveHistoryPopDown();\r
+VOID MoveHistorySet( char movelist[][2*MOVE_LEN], int first, int last, int current, ChessProgramStats_Move * pvInfo );\r
+BOOL MoveHistoryIsUp();\r
+\r
+VOID EvalGraphSet( int first, int last, int current, ChessProgramStats_Move * pvInfo );\r
+VOID EvalGraphPopUp();\r
+VOID EvalGraphPopDown();\r
+BOOL EvalGraphIsUp();\r
+\r
+VOID EngineOutputPopUp();\r
+VOID EngineOutputPopDown();\r
+BOOL EngineOutputIsUp();\r
+VOID EngineOutputUpdate( FrontEndProgramStats * stats );\r
+\r
+VOID EngineOptionsPopup(); // [HGM] settings\r
+\r
+VOID GothicPopUp(char *title, VariantClass variant);\r
/*\r
* Setting "frozen" should disable all user input other than deleting\r
* the window. We do this while engines are initializing themselves.\r
DrawMenuBar(hwndMain);\r
}\r
\r
+/*static*/ int fromX = -1, fromY = -1, toX, toY; // [HGM] moved upstream, so JAWS can use them\r
+\r
+/* JAWS preparation patch (WinBoard for the sight impaired). Define required insertions as empty */\r
+#ifdef JAWS\r
+#include "jaws.c"\r
+#else\r
+#define JAWS_INIT\r
+#define JAWS_ARGS\r
+#define JAWS_ALT_INTERCEPT\r
+#define JAWS_KB_NAVIGATION\r
+#define JAWS_MENU_ITEMS\r
+#define JAWS_SILENCE\r
+#define JAWS_REPLAY\r
+#define JAWS_ACCEL\r
+#define JAWS_COPYRIGHT\r
+#define JAWS_DELETE(X) X\r
+#define SAYMACHINEMOVE()\r
+#define SAY(X)\r
+#endif\r
+\r
/*---------------------------------------------------------------------------*\\r
*\r
* WinMain\r
\r
int APIENTRY\r
WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,\r
- LPSTR lpCmdLine, int nCmdShow)\r
+ LPSTR lpCmdLine, int nCmdShow)\r
{\r
MSG msg;\r
- HANDLE hAccelMain, hAccelNoAlt;\r
+ HANDLE hAccelMain, hAccelNoAlt, hAccelNoICS;\r
+// INITCOMMONCONTROLSEX ex;\r
\r
debugFP = stderr;\r
\r
return (FALSE);\r
}\r
\r
+ JAWS_INIT\r
+\r
+// InitCommonControlsEx(&ex);\r
+ InitCommonControls();\r
+\r
hAccelMain = LoadAccelerators (hInstance, szAppName);\r
hAccelNoAlt = LoadAccelerators (hInstance, "NO_ALT");\r
+ hAccelNoICS = LoadAccelerators( hInstance, "NO_ICS"); /* [AS] No Ctrl-V on ICS!!! */\r
\r
/* Acquire and dispatch messages until a WM_QUIT message is received. */\r
\r
while (GetMessage(&msg, /* message structure */\r
- NULL, /* handle of window receiving the message */\r
- 0, /* lowest message to examine */\r
- 0)) /* highest message to examine */\r
+ NULL, /* handle of window receiving the message */\r
+ 0, /* lowest message to examine */\r
+ 0)) /* highest message to examine */\r
{\r
+\r
+ if(msg.message == WM_CHAR && msg.wParam == '\t') {\r
+ // [HGM] navigate: switch between all windows with tab\r
+ HWND e1 = NULL, e2 = NULL, mh = NULL, hInput = NULL, hText = NULL;\r
+ int i, currentElement = 0;\r
+\r
+ // first determine what element of the chain we come from (if any)\r
+ if(appData.icsActive) {\r
+ hInput = GetDlgItem(hwndConsole, OPT_ConsoleInput);\r
+ hText = GetDlgItem(hwndConsole, OPT_ConsoleText);\r
+ }\r
+ if(engineOutputDialog && EngineOutputIsUp()) {\r
+ e1 = GetDlgItem(engineOutputDialog, IDC_EngineMemo1);\r
+ e2 = GetDlgItem(engineOutputDialog, IDC_EngineMemo2);\r
+ }\r
+ if(moveHistoryDialog && MoveHistoryIsUp()) {\r
+ mh = GetDlgItem(moveHistoryDialog, IDC_MoveHistory);\r
+ }\r
+ if(msg.hwnd == hwndMain) currentElement = 7 ; else\r
+ if(msg.hwnd == engineOutputDialog) currentElement = 2; else\r
+ if(msg.hwnd == e1) currentElement = 2; else\r
+ if(msg.hwnd == e2) currentElement = 3; else\r
+ if(msg.hwnd == moveHistoryDialog) currentElement = 4; else\r
+ if(msg.hwnd == mh) currentElement = 4; else\r
+ if(msg.hwnd == evalGraphDialog) currentElement = 6; else\r
+ if(msg.hwnd == hText) currentElement = 5; else\r
+ if(msg.hwnd == hInput) currentElement = 6; else\r
+ for (i = 0; i < N_BUTTONS; i++) {\r
+ if (buttonDesc[i].hwnd == msg.hwnd) { currentElement = 1; break; }\r
+ }\r
+\r
+ // determine where to go to\r
+ if(currentElement) { HWND h = NULL; int direction = GetKeyState(VK_SHIFT) < 0 ? -1 : 1;\r
+ do {\r
+ currentElement = (currentElement + direction) % 7;\r
+ switch(currentElement) {\r
+ case 0:\r
+ h = hwndMain; break; // passing this case always makes the loop exit\r
+ case 1:\r
+ h = buttonDesc[0].hwnd; break; // could be NULL\r
+ case 2:\r
+ if(!EngineOutputIsUp()) continue; // skip closed auxiliary windows\r
+ h = e1; break;\r
+ case 3:\r
+ if(!EngineOutputIsUp()) continue;\r
+ h = e2; break;\r
+ case 4:\r
+ if(!MoveHistoryIsUp()) continue;\r
+ h = mh; break;\r
+// case 6: // input to eval graph does not seem to get here!\r
+// if(!EvalGraphIsUp()) continue;\r
+// h = evalGraphDialog; break;\r
+ case 5:\r
+ if(!appData.icsActive) continue;\r
+ SAY("display");\r
+ h = hText; break;\r
+ case 6:\r
+ if(!appData.icsActive) continue;\r
+ SAY("input");\r
+ h = hInput; break;\r
+ }\r
+ } while(h == 0);\r
+\r
+ if(currentElement > 4 && IsIconic(hwndConsole)) ShowWindow(hwndConsole, SW_RESTORE);\r
+ if(currentElement < 5 && IsIconic(hwndMain)) ShowWindow(hwndMain, SW_RESTORE); // all open together\r
+ SetFocus(h);\r
+\r
+ continue; // this message now has been processed\r
+ }\r
+ }\r
+\r
if (!(commentDialog && IsDialogMessage(commentDialog, &msg)) &&\r
- !(editTagsDialog && IsDialogMessage(editTagsDialog, &msg)) &&\r
- !(gameListDialog && IsDialogMessage(gameListDialog, &msg)) &&\r
- !(errorDialog && IsDialogMessage(errorDialog, &msg)) &&\r
- !(!frozen && TranslateAccelerator(hwndMain, hAccelMain, &msg)) &&\r
- !(!hwndConsole && TranslateAccelerator(hwndMain, hAccelNoAlt, &msg))) {\r
- TranslateMessage(&msg); /* Translates virtual key codes */\r
- DispatchMessage(&msg); /* Dispatches message to window */\r
+ !(moveHistoryDialog && IsDialogMessage(moveHistoryDialog, &msg)) &&\r
+ !(evalGraphDialog && IsDialogMessage(evalGraphDialog, &msg)) &&\r
+ !(engineOutputDialog && IsDialogMessage(engineOutputDialog, &msg)) &&\r
+ !(editTagsDialog && IsDialogMessage(editTagsDialog, &msg)) &&\r
+ !(gameListDialog && IsDialogMessage(gameListDialog, &msg)) &&\r
+ !(errorDialog && IsDialogMessage(errorDialog, &msg)) &&\r
+ !(!frozen && TranslateAccelerator(hwndMain, hAccelMain, &msg)) && JAWS_ACCEL\r
+ !(!hwndConsole && TranslateAccelerator(hwndMain, hAccelNoICS, &msg)) &&\r
+ !(!hwndConsole && TranslateAccelerator(hwndMain, hAccelNoAlt, &msg))) {\r
+ int done = 0, i; // [HGM] chat: dispatch cat-box messages\r
+ for(i=0; i<MAX_CHAT; i++)\r
+ if(chatHandle[i] && IsDialogMessage(chatHandle[i], &msg)) {\r
+ done = 1; break;\r
+ }\r
+ if(done) continue; // [HGM] chat: end patch\r
+ TranslateMessage(&msg); /* Translates virtual key codes */\r
+ DispatchMessage(&msg); /* Dispatches message to window */\r
}\r
}\r
\r
\r
- return (msg.wParam); /* Returns the value from PostQuitMessage */\r
+ return (msg.wParam); /* Returns the value from PostQuitMessage */\r
}\r
\r
/*---------------------------------------------------------------------------*\\r
*\r
\*---------------------------------------------------------------------------*/\r
\r
+void\r
+SetUserLogo()\r
+{ // update user logo if necessary\r
+ static char oldUserName[MSG_SIZ], *curName;\r
+\r
+ if(appData.autoLogo) {\r
+ curName = UserName();\r
+ if(strcmp(curName, oldUserName)) {\r
+ sprintf(oldUserName, "logos\\%s.bmp", curName);\r
+ userLogo = LoadImage( 0, oldUserName, IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE );\r
+ strcpy(oldUserName, curName);\r
+ }\r
+ }\r
+}\r
+\r
BOOL\r
InitApplication(HINSTANCE hInstance)\r
{\r
/* main window. */\r
\r
wc.style = CS_HREDRAW | CS_VREDRAW; /* Class style(s). */\r
- wc.lpfnWndProc = (WNDPROC)WndProc; /* Window Procedure */\r
- wc.cbClsExtra = 0; /* No per-class extra data. */\r
- wc.cbWndExtra = 0; /* No per-window extra data. */\r
- wc.hInstance = hInstance; /* Owner of this class */\r
+ wc.lpfnWndProc = (WNDPROC)WndProc; /* Window Procedure */\r
+ wc.cbClsExtra = 0; /* No per-class extra data. */\r
+ wc.cbWndExtra = 0; /* No per-window extra data. */\r
+ wc.hInstance = hInstance; /* Owner of this class */\r
wc.hIcon = LoadIcon(hInstance, "icon_white");\r
- wc.hCursor = LoadCursor(NULL, IDC_ARROW); /* Cursor */\r
- wc.hbrBackground = (HBRUSH)(COLOR_WINDOW+1); /* Default color */\r
- wc.lpszMenuName = szAppName; /* Menu name from .RC */\r
- wc.lpszClassName = szAppName; /* Name to register as */\r
+ wc.hCursor = LoadCursor(NULL, IDC_ARROW); /* Cursor */\r
+ wc.hbrBackground = (HBRUSH)(COLOR_WINDOW+1); /* Default color */\r
+ wc.lpszMenuName = szAppName; /* Menu name from .RC */\r
+ wc.lpszClassName = szAppName; /* Name to register as */\r
\r
/* Register the window class and return success/failure code. */\r
if (!RegisterClass(&wc)) return FALSE;\r
int screenHeight, screenWidth;\r
\r
void\r
-EnsureOnScreen(int *x, int *y)\r
+EnsureOnScreen(int *x, int *y, int minX, int minY)\r
{\r
+// int gap = GetSystemMetrics(SM_CYFRAME) + GetSystemMetrics(SM_CYCAPTION);\r
/* Be sure window at (x,y) is not off screen (or even mostly off screen) */\r
if (*x > screenWidth - 32) *x = 0;\r
if (*y > screenHeight - 32) *y = 0;\r
+ if (*x < minX) *x = minX;\r
+ if (*y < minY) *y = minY;\r
}\r
\r
BOOL\r
WINDOWPLACEMENT wp;\r
char *filepart;\r
\r
- hInst = hInstance; /* Store instance handle in our global variable */\r
+ hInst = hInstance; /* Store instance handle in our global variable */\r
\r
if (SearchPath(NULL, "WinBoard.exe", NULL, MSG_SIZ, installDir, &filepart)) {\r
*filepart = NULLCHAR;\r
} else {\r
GetCurrentDirectory(MSG_SIZ, installDir);\r
}\r
+ gameInfo.boardWidth = gameInfo.boardHeight = 8; // [HGM] won't have open window otherwise\r
+ screenWidth = screenHeight = 1000; // [HGM] placement: kludge to allow calling EnsureOnScreen from InitAppData\r
InitAppData(lpCmdLine); /* Get run-time parameters */\r
if (appData.debugMode) {\r
- debugFP = fopen("winboard.debug", "w");\r
+ debugFP = fopen(appData.nameOfDebugFile, "w");\r
setbuf(debugFP, NULL);\r
}\r
\r
InitBackEnd1();\r
\r
+// InitEngineUCI( installDir, &first ); // [HGM] incorporated in InitBackEnd1()\r
+// InitEngineUCI( installDir, &second );\r
+\r
/* Create a main window for this application instance. */\r
hwnd = CreateWindow(szAppName, szTitle,\r
- (WS_OVERLAPPEDWINDOW & ~WS_MAXIMIZEBOX),\r
- CW_USEDEFAULT, 0, CW_USEDEFAULT, 0,\r
- NULL, NULL, hInstance, NULL);\r
+ (WS_OVERLAPPEDWINDOW & ~WS_MAXIMIZEBOX),\r
+ CW_USEDEFAULT, 0, CW_USEDEFAULT, 0,\r
+ NULL, NULL, hInstance, NULL);\r
hwndMain = hwnd;\r
\r
/* If window could not be created, return "failure" */\r
return (FALSE);\r
}\r
\r
+ /* [HGM] logo: Load logos if specified (must be done before InitDrawingSizes) */\r
+ if( appData.firstLogo && appData.firstLogo[0] != NULLCHAR) {\r
+ first.programLogo = LoadImage( 0, appData.firstLogo, IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE );\r
+\r
+ if (first.programLogo == NULL && appData.debugMode) {\r
+ fprintf( debugFP, "Unable to load logo bitmap '%s'\n", appData.firstLogo );\r
+ }\r
+ } else if(appData.autoLogo) {\r
+ if(appData.firstDirectory && appData.firstDirectory[0]) {\r
+ char buf[MSG_SIZ];\r
+ sprintf(buf, "%s/logo.bmp", appData.firstDirectory);\r
+ first.programLogo = LoadImage( 0, buf, IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE );\r
+ }\r
+ }\r
+\r
+ if( appData.secondLogo && appData.secondLogo[0] != NULLCHAR) {\r
+ second.programLogo = LoadImage( 0, appData.secondLogo, IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE );\r
+\r
+ if (second.programLogo == NULL && appData.debugMode) {\r
+ fprintf( debugFP, "Unable to load logo bitmap '%s'\n", appData.secondLogo );\r
+ }\r
+ } else if(appData.autoLogo) {\r
+ char buf[MSG_SIZ];\r
+ if(appData.icsActive) { // [HGM] logo: in ICS mode second can be used for ICS\r
+ sprintf(buf, "logos\\%s.bmp", appData.icsHost);\r
+ second.programLogo = LoadImage( 0, buf, IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE );\r
+ } else\r
+ if(appData.secondDirectory && appData.secondDirectory[0]) {\r
+ sprintf(buf, "%s\\logo.bmp", appData.secondDirectory);\r
+ second.programLogo = LoadImage( 0, buf, IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE );\r
+ }\r
+ }\r
+\r
+ SetUserLogo();\r
+\r
iconWhite = LoadIcon(hInstance, "icon_white");\r
iconBlack = LoadIcon(hInstance, "icon_black");\r
iconCurrent = iconWhite;\r
for (ibs = (int) NUM_SIZES - 1; ibs >= 0; ibs--) {\r
/* Compute window size for each board size, and use the largest\r
size that fits on this screen as the default. */\r
- InitDrawingSizes((BoardSize)ibs, 0);\r
+ InitDrawingSizes((BoardSize)(ibs+1000), 0);\r
if (boardSize == (BoardSize)-1 &&\r
- winHeight <= screenHeight && winWidth <= screenWidth) {\r
+ winH <= screenHeight\r
+ - GetSystemMetrics(SM_CYFRAME) - GetSystemMetrics(SM_CYCAPTION) - 10\r
+ && winW <= screenWidth) {\r
boardSize = (BoardSize)ibs;\r
}\r
}\r
+\r
InitDrawingSizes(boardSize, 0);\r
InitMenuChecks();\r
buttonCount = GetSystemMetrics(SM_CMOUSEBUTTONS);\r
\r
- /* Make a console window if needed */\r
- if (appData.icsActive) {\r
- ConsoleCreate();\r
+ /* [AS] Load textures if specified */\r
+ ZeroMemory( &backTextureSquareInfo, sizeof(backTextureSquareInfo) );\r
+\r
+ if( appData.liteBackTextureFile && appData.liteBackTextureFile[0] != NULLCHAR && appData.liteBackTextureFile[0] != '*' ) {\r
+ liteBackTexture = LoadImage( 0, appData.liteBackTextureFile, IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE );\r
+ liteBackTextureMode = appData.liteBackTextureMode;\r
+\r
+ if (liteBackTexture == NULL && appData.debugMode) {\r
+ fprintf( debugFP, "Unable to load lite texture bitmap '%s'\n", appData.liteBackTextureFile );\r
+ }\r
+ }\r
+\r
+ if( appData.darkBackTextureFile && appData.darkBackTextureFile[0] != NULLCHAR && appData.darkBackTextureFile[0] != '*' ) {\r
+ darkBackTexture = LoadImage( 0, appData.darkBackTextureFile, IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE );\r
+ darkBackTextureMode = appData.darkBackTextureMode;\r
+\r
+ if (darkBackTexture == NULL && appData.debugMode) {\r
+ fprintf( debugFP, "Unable to load dark texture bitmap '%s'\n", appData.darkBackTextureFile );\r
+ }\r
+ }\r
+\r
+ mysrandom( (unsigned) time(NULL) );\r
+\r
+ /* [AS] Restore layout */\r
+ if( wpMoveHistory.visible ) {\r
+ MoveHistoryPopUp();\r
+ }\r
+\r
+ if( wpEvalGraph.visible ) {\r
+ EvalGraphPopUp();\r
+ }\r
+\r
+ if( wpEngineOutput.visible ) {\r
+ EngineOutputPopUp();\r
}\r
\r
InitBackEnd2();\r
\r
/* Make the window visible; update its client area; and return "success" */\r
- EnsureOnScreen(&boardX, &boardY);\r
+ EnsureOnScreen(&boardX, &boardY, minX, minY);\r
wp.length = sizeof(WINDOWPLACEMENT);\r
wp.flags = 0;\r
wp.showCmd = nCmdShow;\r
wp.rcNormalPosition.bottom = boardY + winHeight;\r
SetWindowPlacement(hwndMain, &wp);\r
\r
- SetWindowPos(hwndMain, alwaysOnTop ? HWND_TOPMOST : HWND_NOTOPMOST,\r
- 0, 0, 0, 0, SWP_NOMOVE|SWP_NOSIZE);\r
+ if(!appData.noGUI) SetWindowPos(hwndMain, alwaysOnTop ? HWND_TOPMOST : HWND_NOTOPMOST,\r
+ 0, 0, 0, 0, SWP_NOMOVE|SWP_NOSIZE);\r
+\r
if (hwndConsole) {\r
#if AOT_CONSOLE\r
SetWindowPos(hwndConsole, alwaysOnTop ? HWND_TOPMOST : HWND_NOTOPMOST,\r
#endif\r
ShowWindow(hwndConsole, nCmdShow);\r
}\r
- UpdateWindow(hwnd);\r
+ if(!appData.noGUI) UpdateWindow(hwnd); else ShowWindow(hwnd, SW_MINIMIZE);\r
+ if(gameListDialog) SetFocus(gameListDialog); // [HGM] jaws: for if we clicked multi-game game file\r
\r
return TRUE;\r
\r
\r
\r
typedef enum {\r
- ArgString, ArgInt, ArgFloat, ArgBoolean, ArgTrue, ArgFalse, ArgNone, \r
+ ArgString, ArgInt, ArgFloat, ArgBoolean, ArgTrue, ArgFalse, ArgNone,\r
ArgColor, ArgAttribs, ArgFilename, ArgBoardSize, ArgFont, ArgCommSettings,\r
- ArgSettingsFilename\r
+ ArgSettingsFilename,\r
+ ArgX, ArgY, ArgZ // [HGM] placement: for window-placement options stored relative to main window\r
} ArgType;\r
\r
typedef struct {\r
{ "loadGameFile", ArgFilename, (LPVOID) &appData.loadGameFile, FALSE },\r
{ "", ArgNone, NULL },\r
/* keyword arguments */\r
+ JAWS_ARGS\r
{ "whitePieceColor", ArgColor, (LPVOID) &whitePieceColor, TRUE },\r
{ "wpc", ArgColor, (LPVOID) &whitePieceColor, FALSE },\r
{ "blackPieceColor", ArgColor, (LPVOID) &blackPieceColor, TRUE },\r
{ "popup", ArgTrue, (LPVOID) &appData.popupMoveErrors, FALSE },\r
{ "xpopup", ArgFalse, (LPVOID) &appData.popupMoveErrors, FALSE },\r
{ "-popup", ArgFalse, (LPVOID) &appData.popupMoveErrors, FALSE },\r
- { "popUpErrors", ArgBoolean, (LPVOID) &appData.popupMoveErrors, \r
+ { "popUpErrors", ArgBoolean, (LPVOID) &appData.popupMoveErrors,\r
FALSE }, /* only so that old WinBoard.ini files from betas can be read */\r
{ "clockFont", ArgFont, (LPVOID) CLOCK_FONT, TRUE },\r
{ "messageFont", ArgFont, (LPVOID) MESSAGE_FONT, TRUE },\r
{ "tagsFont", ArgFont, (LPVOID) EDITTAGS_FONT, TRUE },\r
{ "commentFont", ArgFont, (LPVOID) COMMENT_FONT, TRUE },\r
{ "icsFont", ArgFont, (LPVOID) CONSOLE_FONT, TRUE },\r
+ { "moveHistoryFont", ArgFont, (LPVOID) MOVEHISTORY_FONT, TRUE }, /* [AS] */\r
{ "boardSize", ArgBoardSize, (LPVOID) &boardSize,\r
TRUE }, /* must come after all fonts */\r
{ "size", ArgBoardSize, (LPVOID) &boardSize, FALSE },\r
{ "soundMove", ArgFilename, (LPVOID) &sounds[(int)SoundMove].name, TRUE },\r
{ "soundBell", ArgFilename, (LPVOID) &sounds[(int)SoundBell].name, TRUE },\r
{ "soundIcsWin", ArgFilename, (LPVOID) &sounds[(int)SoundIcsWin].name,TRUE },\r
- { "soundIcsLoss", ArgFilename, \r
+ { "soundIcsLoss", ArgFilename,\r
(LPVOID) &sounds[(int)SoundIcsLoss].name, TRUE },\r
- { "soundIcsDraw", ArgFilename, \r
+ { "soundIcsDraw", ArgFilename,\r
(LPVOID) &sounds[(int)SoundIcsDraw].name, TRUE },\r
- { "soundIcsUnfinished", ArgFilename, \r
+ { "soundIcsUnfinished", ArgFilename,\r
(LPVOID) &sounds[(int)SoundIcsUnfinished].name, TRUE},\r
- { "soundIcsAlarm", ArgFilename, \r
+ { "soundIcsAlarm", ArgFilename,\r
(LPVOID) &sounds[(int)SoundAlarm].name, TRUE },\r
{ "reuseFirst", ArgBoolean, (LPVOID) &appData.reuseFirst, FALSE },\r
{ "reuse", ArgTrue, (LPVOID) &appData.reuseFirst, FALSE },\r
{ "xreuse2", ArgFalse, (LPVOID) &appData.reuseSecond, FALSE },\r
{ "-reuse2", ArgFalse, (LPVOID) &appData.reuseSecond, FALSE },\r
{ "comPortSettings", ArgCommSettings, (LPVOID) &dcb, TRUE },\r
- { "x", ArgInt, (LPVOID) &boardX, TRUE },\r
- { "y", ArgInt, (LPVOID) &boardY, TRUE },\r
- { "icsX", ArgInt, (LPVOID) &consoleX, TRUE },\r
- { "icsY", ArgInt, (LPVOID) &consoleY, TRUE },\r
- { "icsW", ArgInt, (LPVOID) &consoleW, TRUE },\r
- { "icsH", ArgInt, (LPVOID) &consoleH, TRUE },\r
- { "analysisX", ArgInt, (LPVOID) &analysisX, TRUE },\r
- { "analysisY", ArgInt, (LPVOID) &analysisY, TRUE },\r
- { "analysisW", ArgInt, (LPVOID) &analysisW, TRUE },\r
- { "analysisH", ArgInt, (LPVOID) &analysisH, TRUE },\r
- { "commentX", ArgInt, (LPVOID) &commentX, TRUE },\r
- { "commentY", ArgInt, (LPVOID) &commentY, TRUE },\r
- { "commentW", ArgInt, (LPVOID) &commentW, TRUE },\r
- { "commentH", ArgInt, (LPVOID) &commentH, TRUE },\r
- { "tagsX", ArgInt, (LPVOID) &editTagsX, TRUE },\r
- { "tagsY", ArgInt, (LPVOID) &editTagsY, TRUE },\r
- { "tagsW", ArgInt, (LPVOID) &editTagsW, TRUE },\r
- { "tagsH", ArgInt, (LPVOID) &editTagsH, TRUE },\r
- { "gameListX", ArgInt, (LPVOID) &gameListX, TRUE },\r
- { "gameListY", ArgInt, (LPVOID) &gameListY, TRUE },\r
- { "gameListW", ArgInt, (LPVOID) &gameListW, TRUE },\r
- { "gameListH", ArgInt, (LPVOID) &gameListH, TRUE },\r
{ "settingsFile", ArgSettingsFilename, (LPVOID) &settingsFileName, FALSE },\r
{ "ini", ArgSettingsFilename, (LPVOID) &settingsFileName, FALSE },\r
{ "saveSettingsOnExit", ArgBoolean, (LPVOID) &saveSettingsOnExit, TRUE },\r
{ "initialMode", ArgString, (LPVOID) &appData.initialMode, FALSE },\r
{ "mode", ArgString, (LPVOID) &appData.initialMode, FALSE },\r
{ "variant", ArgString, (LPVOID) &appData.variant, FALSE },\r
- { "firstProtocolVersion", ArgInt, (LPVOID) &appData.firstProtocolVersion,\r
- FALSE },\r
- { "secondProtocolVersion", ArgInt, (LPVOID) &appData.secondProtocolVersion,\r
- FALSE },\r
+ { "firstProtocolVersion", ArgInt, (LPVOID) &appData.firstProtocolVersion, FALSE },\r
+ { "secondProtocolVersion", ArgInt, (LPVOID) &appData.secondProtocolVersion,FALSE },\r
{ "showButtonBar", ArgBoolean, (LPVOID) &appData.showButtonBar, TRUE },\r
{ "buttons", ArgTrue, (LPVOID) &appData.showButtonBar, FALSE },\r
{ "xbuttons", ArgFalse, (LPVOID) &appData.showButtonBar, FALSE },\r
{ "-buttons", ArgFalse, (LPVOID) &appData.showButtonBar, FALSE },\r
+ /* [AS] New features */\r
+ { "firstScoreAbs", ArgBoolean, (LPVOID) &appData.firstScoreIsAbsolute, FALSE },\r
+ { "secondScoreAbs", ArgBoolean, (LPVOID) &appData.secondScoreIsAbsolute, FALSE },\r
+ { "pgnExtendedInfo", ArgBoolean, (LPVOID) &appData.saveExtendedInfoInPGN, TRUE },\r
+ { "hideThinkingFromHuman", ArgBoolean, (LPVOID) &appData.hideThinkingFromHuman, TRUE },\r
+ { "liteBackTextureFile", ArgString, (LPVOID) &appData.liteBackTextureFile, TRUE },\r
+ { "darkBackTextureFile", ArgString, (LPVOID) &appData.darkBackTextureFile, TRUE },\r
+ { "liteBackTextureMode", ArgInt, (LPVOID) &appData.liteBackTextureMode, TRUE },\r
+ { "darkBackTextureMode", ArgInt, (LPVOID) &appData.darkBackTextureMode, TRUE },\r
+ { "renderPiecesWithFont", ArgString, (LPVOID) &appData.renderPiecesWithFont, TRUE },\r
+ { "fontPieceToCharTable", ArgString, (LPVOID) &appData.fontToPieceTable, TRUE },\r
+ { "fontPieceBackColorWhite", ArgColor, (LPVOID) &appData.fontBackColorWhite, TRUE },\r
+ { "fontPieceForeColorWhite", ArgColor, (LPVOID) &appData.fontForeColorWhite, TRUE },\r
+ { "fontPieceBackColorBlack", ArgColor, (LPVOID) &appData.fontBackColorBlack, TRUE },\r
+ { "fontPieceForeColorBlack", ArgColor, (LPVOID) &appData.fontForeColorBlack, TRUE },\r
+ { "fontPieceSize", ArgInt, (LPVOID) &appData.fontPieceSize, TRUE },\r
+ { "overrideLineGap", ArgInt, (LPVOID) &appData.overrideLineGap, TRUE },\r
+ { "adjudicateLossThreshold", ArgInt, (LPVOID) &appData.adjudicateLossThreshold, TRUE },\r
+ { "delayBeforeQuit", ArgInt, (LPVOID) &appData.delayBeforeQuit, TRUE },\r
+ { "delayAfterQuit", ArgInt, (LPVOID) &appData.delayAfterQuit, TRUE },\r
+ { "nameOfDebugFile", ArgFilename, (LPVOID) &appData.nameOfDebugFile, FALSE },\r
+ { "debugfile", ArgFilename, (LPVOID) &appData.nameOfDebugFile, FALSE },\r
+ { "pgnEventHeader", ArgString, (LPVOID) &appData.pgnEventHeader, TRUE },\r
+ { "defaultFrcPosition", ArgInt, (LPVOID) &appData.defaultFrcPosition, TRUE },\r
+ { "gameListTags", ArgString, (LPVOID) &appData.gameListTags, TRUE },\r
+ { "saveOutOfBookInfo", ArgBoolean, (LPVOID) &appData.saveOutOfBookInfo, TRUE },\r
+ { "showEvalInMoveHistory", ArgBoolean, (LPVOID) &appData.showEvalInMoveHistory, TRUE },\r
+ { "evalHistColorWhite", ArgColor, (LPVOID) &appData.evalHistColorWhite, TRUE },\r
+ { "evalHistColorBlack", ArgColor, (LPVOID) &appData.evalHistColorBlack, TRUE },\r
+ { "highlightMoveWithArrow", ArgBoolean, (LPVOID) &appData.highlightMoveWithArrow, TRUE },\r
+ { "highlightArrowColor", ArgColor, (LPVOID) &appData.highlightArrowColor, TRUE },\r
+ { "stickyWindows", ArgBoolean, (LPVOID) &appData.useStickyWindows, TRUE },\r
+ { "adjudicateDrawMoves", ArgInt, (LPVOID) &appData.adjudicateDrawMoves, TRUE },\r
+ { "autoDisplayComment", ArgBoolean, (LPVOID) &appData.autoDisplayComment, TRUE },\r
+ { "autoDisplayTags", ArgBoolean, (LPVOID) &appData.autoDisplayTags, TRUE },\r
+ { "firstIsUCI", ArgBoolean, (LPVOID) &appData.firstIsUCI, FALSE },\r
+ { "fUCI", ArgTrue, (LPVOID) &appData.firstIsUCI, FALSE },\r
+ { "secondIsUCI", ArgBoolean, (LPVOID) &appData.secondIsUCI, FALSE },\r
+ { "sUCI", ArgTrue, (LPVOID) &appData.secondIsUCI, FALSE },\r
+ { "firstHasOwnBookUCI", ArgBoolean, (LPVOID) &appData.firstHasOwnBookUCI, FALSE },\r
+ { "fNoOwnBookUCI", ArgFalse, (LPVOID) &appData.firstHasOwnBookUCI, FALSE },\r
+ { "firstXBook", ArgFalse, (LPVOID) &appData.firstHasOwnBookUCI, FALSE },\r
+ { "secondHasOwnBookUCI", ArgBoolean, (LPVOID) &appData.secondHasOwnBookUCI, FALSE },\r
+ { "sNoOwnBookUCI", ArgFalse, (LPVOID) &appData.secondHasOwnBookUCI, FALSE },\r
+ { "secondXBook", ArgFalse, (LPVOID) &appData.secondHasOwnBookUCI, FALSE },\r
+ { "polyglotDir", ArgFilename, (LPVOID) &appData.polyglotDir, TRUE },\r
+ { "usePolyglotBook", ArgBoolean, (LPVOID) &appData.usePolyglotBook, TRUE },\r
+ { "polyglotBook", ArgFilename, (LPVOID) &appData.polyglotBook, TRUE },\r
+ { "defaultHashSize", ArgInt, (LPVOID) &appData.defaultHashSize, TRUE },\r
+ { "defaultCacheSizeEGTB", ArgInt, (LPVOID) &appData.defaultCacheSizeEGTB, TRUE },\r
+ { "defaultPathEGTB", ArgFilename, (LPVOID) &appData.defaultPathEGTB, TRUE },\r
+\r
+ /* [HGM] board-size, adjudication and misc. options */\r
+ { "boardWidth", ArgInt, (LPVOID) &appData.NrFiles, TRUE },\r
+ { "boardHeight", ArgInt, (LPVOID) &appData.NrRanks, TRUE },\r
+ { "holdingsSize", ArgInt, (LPVOID) &appData.holdingsSize, TRUE },\r
+ { "matchPause", ArgInt, (LPVOID) &appData.matchPause, TRUE },\r
+ { "pieceToCharTable", ArgString, (LPVOID) &appData.pieceToCharTable, FALSE },\r
+ { "flipBlack", ArgBoolean, (LPVOID) &appData.upsideDown, TRUE },\r
+ { "allWhite", ArgBoolean, (LPVOID) &appData.allWhite, TRUE },\r
+ { "alphaRank", ArgBoolean, (LPVOID) &appData.alphaRank, FALSE },\r
+ { "firstAlphaRank", ArgBoolean, (LPVOID) &first.alphaRank, FALSE },\r
+ { "secondAlphaRank", ArgBoolean, (LPVOID) &second.alphaRank, FALSE },\r
+ { "testClaims", ArgBoolean, (LPVOID) &appData.testClaims, TRUE },\r
+ { "checkMates", ArgBoolean, (LPVOID) &appData.checkMates, TRUE },\r
+ { "materialDraws", ArgBoolean, (LPVOID) &appData.materialDraws, TRUE },\r
+ { "trivialDraws", ArgBoolean, (LPVOID) &appData.trivialDraws, TRUE },\r
+ { "ruleMoves", ArgInt, (LPVOID) &appData.ruleMoves, TRUE },\r
+ { "repeatsToDraw", ArgInt, (LPVOID) &appData.drawRepeats, TRUE },\r
+ { "autoKibitz", ArgTrue, (LPVOID) &appData.autoKibitz, FALSE },\r
+ { "engineDebugOutput", ArgInt, (LPVOID) &appData.engineComments, FALSE },\r
+ { "userName", ArgString, (LPVOID) &appData.userName, FALSE },\r
+ { "rewindIndex", ArgInt, (LPVOID) &appData.rewindIndex, FALSE },\r
+ { "sameColorGames", ArgInt, (LPVOID) &appData.sameColorGames, FALSE },\r
+ { "smpCores", ArgInt, (LPVOID) &appData.smpCores, TRUE },\r
+ { "egtFormats", ArgString, (LPVOID) &appData.egtFormats, TRUE },\r
+ { "niceEngines", ArgInt, (LPVOID) &appData.niceEngines, TRUE },\r
+ { "firstLogo", ArgFilename, (LPVOID) &appData.firstLogo, FALSE },\r
+ { "secondLogo", ArgFilename, (LPVOID) &appData.secondLogo, FALSE },\r
+ { "autoLogo", ArgBoolean, (LPVOID) &appData.autoLogo, TRUE },\r
+ { "firstOptions", ArgString, (LPVOID) &appData.firstOptions, FALSE },\r
+ { "secondOptions", ArgString, (LPVOID) &appData.secondOptions, FALSE },\r
+ { "firstNeedsNoncompliantFEN", ArgString, (LPVOID) &appData.fenOverride1, FALSE },\r
+ { "secondNeedsNoncompliantFEN", ArgString, (LPVOID) &appData.fenOverride2, FALSE },\r
+ { "keepAlive", ArgInt, (LPVOID) &appData.keepAlive, FALSE },\r
+ { "icstype", ArgInt, (LPVOID) &ics_type, FALSE },\r
+ { "forceIllegalMoves", ArgTrue, (LPVOID) &appData.forceIllegal, FALSE },\r
+\r
#ifdef ZIPPY\r
{ "zippyTalk", ArgBoolean, (LPVOID) &appData.zippyTalk, FALSE },\r
{ "zt", ArgTrue, (LPVOID) &appData.zippyTalk, FALSE },\r
{ "zippyVariants", ArgString, (LPVOID) &appData.zippyVariants, FALSE },\r
{ "zippyMaxGames", ArgInt, (LPVOID)&appData.zippyMaxGames, FALSE },\r
{ "zippyReplayTimeout", ArgInt, (LPVOID)&appData.zippyReplayTimeout, FALSE },\r
+ { "zippyShortGame", ArgInt, (LPVOID)&appData.zippyShortGame, FALSE },\r
/* Kludge to allow winboard.ini files from buggy 4.0.4 to be read: */\r
{ "zippyReplyTimeout", ArgInt, (LPVOID)&junk, FALSE },\r
#endif\r
+ /* [HGM] options for broadcasting and time odds */\r
+ { "serverMoves", ArgString, (LPVOID) &appData.serverMovesName, FALSE },\r
+ { "suppressLoadMoves", ArgBoolean, (LPVOID) &appData.suppressLoadMoves, FALSE },\r
+ { "serverPause", ArgInt, (LPVOID) &appData.serverPause, FALSE },\r
+ { "firstTimeOdds", ArgInt, (LPVOID) &appData.firstTimeOdds, FALSE },\r
+ { "secondTimeOdds", ArgInt, (LPVOID) &appData.secondTimeOdds, FALSE },\r
+ { "timeOddsMode", ArgInt, (LPVOID) &appData.timeOddsMode, TRUE },\r
+ { "firstAccumulateTC", ArgInt, (LPVOID) &appData.firstAccumulateTC, FALSE },\r
+ { "secondAccumulateTC", ArgInt, (LPVOID) &appData.secondAccumulateTC, FALSE },\r
+ { "firstNPS", ArgInt, (LPVOID) &appData.firstNPS, FALSE },\r
+ { "secondNPS", ArgInt, (LPVOID) &appData.secondNPS, FALSE },\r
+ { "noGUI", ArgTrue, (LPVOID) &appData.noGUI, FALSE },\r
+\r
+ // [HGM] placement: put all window layouts last in ini file, but man X,Y before all others\r
+ { "minX", ArgZ, (LPVOID) &minX, FALSE }, // [HGM] placement: to make suer auxialary windows can be placed\r
+ { "minY", ArgZ, (LPVOID) &minY, FALSE },\r
+ { "winWidth", ArgInt, (LPVOID) &winWidth, TRUE }, // [HGM] placement: dummies to remember right & bottom\r
+ { "winHeight", ArgInt, (LPVOID) &winHeight, TRUE }, // for attaching auxiliary windows to them\r
+ { "x", ArgInt, (LPVOID) &boardX, TRUE },\r
+ { "y", ArgInt, (LPVOID) &boardY, TRUE },\r
+ { "icsX", ArgX, (LPVOID) &wpConsole.x, TRUE },\r
+ { "icsY", ArgY, (LPVOID) &wpConsole.y, TRUE },\r
+ { "icsW", ArgInt, (LPVOID) &wpConsole.width, TRUE },\r
+ { "icsH", ArgInt, (LPVOID) &wpConsole.height, TRUE },\r
+ { "analysisX", ArgX, (LPVOID) &analysisX, FALSE }, // [HGM] placement: analysis window no longer exists\r
+ { "analysisY", ArgY, (LPVOID) &analysisY, FALSE }, // provided for compatibility with old ini files\r
+ { "analysisW", ArgInt, (LPVOID) &analysisW, FALSE },\r
+ { "analysisH", ArgInt, (LPVOID) &analysisH, FALSE },\r
+ { "commentX", ArgX, (LPVOID) &commentX, TRUE },\r
+ { "commentY", ArgY, (LPVOID) &commentY, TRUE },\r
+ { "commentW", ArgInt, (LPVOID) &commentW, TRUE },\r
+ { "commentH", ArgInt, (LPVOID) &commentH, TRUE },\r
+ { "tagsX", ArgX, (LPVOID) &editTagsX, TRUE },\r
+ { "tagsY", ArgY, (LPVOID) &editTagsY, TRUE },\r
+ { "tagsW", ArgInt, (LPVOID) &editTagsW, TRUE },\r
+ { "tagsH", ArgInt, (LPVOID) &editTagsH, TRUE },\r
+ { "gameListX", ArgX, (LPVOID) &wpGameList.x, TRUE },\r
+ { "gameListY", ArgY, (LPVOID) &wpGameList.y, TRUE },\r
+ { "gameListW", ArgInt, (LPVOID) &wpGameList.width, TRUE },\r
+ { "gameListH", ArgInt, (LPVOID) &wpGameList.height, TRUE },\r
+ /* [AS] Layout stuff */\r
+ { "moveHistoryUp", ArgBoolean, (LPVOID) &wpMoveHistory.visible, TRUE },\r
+ { "moveHistoryX", ArgX, (LPVOID) &wpMoveHistory.x, TRUE },\r
+ { "moveHistoryY", ArgY, (LPVOID) &wpMoveHistory.y, TRUE },\r
+ { "moveHistoryW", ArgInt, (LPVOID) &wpMoveHistory.width, TRUE },\r
+ { "moveHistoryH", ArgInt, (LPVOID) &wpMoveHistory.height, TRUE },\r
+\r
+ { "evalGraphUp", ArgBoolean, (LPVOID) &wpEvalGraph.visible, TRUE },\r
+ { "evalGraphX", ArgX, (LPVOID) &wpEvalGraph.x, TRUE },\r
+ { "evalGraphY", ArgY, (LPVOID) &wpEvalGraph.y, TRUE },\r
+ { "evalGraphW", ArgInt, (LPVOID) &wpEvalGraph.width, TRUE },\r
+ { "evalGraphH", ArgInt, (LPVOID) &wpEvalGraph.height, TRUE },\r
+\r
+ { "engineOutputUp", ArgBoolean, (LPVOID) &wpEngineOutput.visible, TRUE },\r
+ { "engineOutputX", ArgX, (LPVOID) &wpEngineOutput.x, TRUE },\r
+ { "engineOutputY", ArgY, (LPVOID) &wpEngineOutput.y, TRUE },\r
+ { "engineOutputW", ArgInt, (LPVOID) &wpEngineOutput.width, TRUE },\r
+ { "engineOutputH", ArgInt, (LPVOID) &wpEngineOutput.height, TRUE },\r
+\r
{ NULL, ArgNone, NULL, FALSE }\r
};\r
\r
while (*p && !isdigit(*p)) {\r
*q++ = *p++;\r
if (q - mfp->faceName >= sizeof(mfp->faceName))\r
- ExitArgError("Font name too long:", name);\r
+ ExitArgError("Font name too long:", name);\r
}\r
while (q > mfp->faceName && q[-1] == ' ') q--;\r
*q = NULLCHAR;\r
\r
count = sscanf(name, "#%2x%2x%2x", &red, &green, &blue);\r
if (count != 3) {\r
- count = sscanf(name, "%3d%*[^0-9]%3d%*[^0-9]%3d", \r
+ count = sscanf(name, "%3d%*[^0-9]%3d%*[^0-9]%3d",\r
&red, &green, &blue);\r
}\r
if (count != 3) {\r
FILE* f = (FILE*) getClosure;\r
\r
c = getc(f);\r
+ if (c == '\r') c = getc(f); // work around DOS format files by bypassing the '\r' completely\r
if (c == EOF)\r
return NULLCHAR;\r
else\r
{\r
char *dummy;\r
FILE *f;\r
+ int ok; char buf[MSG_SIZ];\r
\r
- if (SearchPath(installDir, name, NULL, MSG_SIZ, fullname, &dummy)) {\r
+ ok = SearchPath(installDir, name, NULL, MSG_SIZ, fullname, &dummy);\r
+ if(!ok && strchr(name, '.') == NULL) { // [HGM] append default file-name extension '.ini' when needed\r
+ sprintf(buf, "%s.ini", name);\r
+ ok = SearchPath(installDir, buf, NULL, MSG_SIZ, fullname, &dummy);\r
+ }\r
+ if (ok) {\r
f = fopen(fullname, "r");\r
if (f != NULL) {\r
ParseArgs(FileGet, f);\r
/* Switch */\r
q = argName;\r
while (ch != ' ' && ch != '=' && ch != ':' && ch != NULLCHAR &&\r
- ch != '\n' && ch != '\t') {\r
- *q++ = ch;\r
- ch = get(cl);\r
+ ch != '\n' && ch != '\t') {\r
+ *q++ = ch;\r
+ ch = get(cl);\r
}\r
*q = NULLCHAR;\r
\r
for (ad = argDescriptors; ad->argName != NULL; ad++)\r
- if (strcmp(ad->argName, argName + 1) == 0) break;\r
+ if (strcmp(ad->argName, argName + 1) == 0) break;\r
\r
if (ad->argName == NULL)\r
- ExitArgError("Unrecognized argument", argName);\r
+ ExitArgError("Unrecognized argument", argName);\r
\r
} else if (ch == '@') {\r
/* Indirection file */\r
start = ch;\r
ch = get(cl);\r
while (start) {\r
- switch (ch) {\r
- case NULLCHAR:\r
- start = NULLCHAR;\r
- break;\r
- \r
- case '}':\r
- ch = get(cl);\r
- start = NULLCHAR;\r
- break;\r
-\r
- default:\r
- *q++ = ch;\r
- ch = get(cl);\r
- break;\r
- }\r
- } \r
+ switch (ch) {\r
+ case NULLCHAR:\r
+ start = NULLCHAR;\r
+ break;\r
+\r
+ case '}':\r
+ ch = get(cl);\r
+ start = NULLCHAR;\r
+ break;\r
+\r
+ default:\r
+ *q++ = ch;\r
+ ch = get(cl);\r
+ break;\r
+ }\r
+ }\r
} else if (ch == '\'' || ch == '"') {\r
// Quoting with ' ' or " ", with \ as escape character.\r
// Inconvenient for long strings that may contain Windows filenames.\r
start = ch;\r
ch = get(cl);\r
while (start) {\r
- switch (ch) {\r
- case NULLCHAR:\r
- start = NULLCHAR;\r
- break;\r
+ switch (ch) {\r
+ case NULLCHAR:\r
+ start = NULLCHAR;\r
+ break;\r
\r
- default:\r
+ default:\r
not_special:\r
- *q++ = ch;\r
- ch = get(cl);\r
- break;\r
-\r
- case '\'':\r
- case '\"':\r
- if (ch == start) {\r
- ch = get(cl);\r
- start = NULLCHAR;\r
- break;\r
- } else {\r
- goto not_special;\r
- }\r
-\r
- case '\\':\r
+ *q++ = ch;\r
+ ch = get(cl);\r
+ break;\r
+\r
+ case '\'':\r
+ case '\"':\r
+ if (ch == start) {\r
+ ch = get(cl);\r
+ start = NULLCHAR;\r
+ break;\r
+ } else {\r
+ goto not_special;\r
+ }\r
+\r
+ case '\\':\r
if (ad->argType == ArgFilename\r
- || ad->argType == ArgSettingsFilename) {\r
- goto not_special;\r
- }\r
- ch = get(cl);\r
- switch (ch) {\r
- case NULLCHAR:\r
- ExitArgError("Incomplete \\ escape in value for", argName);\r
- break;\r
- case 'n':\r
- *q++ = '\n';\r
- ch = get(cl);\r
- break;\r
- case 'r':\r
- *q++ = '\r';\r
- ch = get(cl);\r
- break;\r
- case 't':\r
- *q++ = '\t';\r
- ch = get(cl);\r
- break;\r
- case 'b':\r
- *q++ = '\b';\r
- ch = get(cl);\r
- break;\r
- case 'f':\r
- *q++ = '\f';\r
- ch = get(cl);\r
- break;\r
- default:\r
- octval = 0;\r
- for (i = 0; i < 3; i++) {\r
- if (ch >= '0' && ch <= '7') {\r
- octval = octval*8 + (ch - '0');\r
- ch = get(cl);\r
- } else {\r
- break;\r
- }\r
- }\r
- if (i > 0) {\r
- *q++ = (char) octval;\r
- } else {\r
- *q++ = ch;\r
- ch = get(cl);\r
- }\r
- break;\r
- }\r
- break;\r
- }\r
+ || ad->argType == ArgSettingsFilename) {\r
+ goto not_special;\r
+ }\r
+ ch = get(cl);\r
+ switch (ch) {\r
+ case NULLCHAR:\r
+ ExitArgError("Incomplete \\ escape in value for", argName);\r
+ break;\r
+ case 'n':\r
+ *q++ = '\n';\r
+ ch = get(cl);\r
+ break;\r
+ case 'r':\r
+ *q++ = '\r';\r
+ ch = get(cl);\r
+ break;\r
+ case 't':\r
+ *q++ = '\t';\r
+ ch = get(cl);\r
+ break;\r
+ case 'b':\r
+ *q++ = '\b';\r
+ ch = get(cl);\r
+ break;\r
+ case 'f':\r
+ *q++ = '\f';\r
+ ch = get(cl);\r
+ break;\r
+ default:\r
+ octval = 0;\r
+ for (i = 0; i < 3; i++) {\r
+ if (ch >= '0' && ch <= '7') {\r
+ octval = octval*8 + (ch - '0');\r
+ ch = get(cl);\r
+ } else {\r
+ break;\r
+ }\r
+ }\r
+ if (i > 0) {\r
+ *q++ = (char) octval;\r
+ } else {\r
+ *q++ = ch;\r
+ ch = get(cl);\r
+ }\r
+ break;\r
+ }\r
+ break;\r
+ }\r
}\r
} else {\r
while (ch != ' ' && ch != NULLCHAR && ch != '\t' && ch != '\n') {\r
- *q++ = ch;\r
- ch = get(cl);\r
+ *q++ = ch;\r
+ ch = get(cl);\r
}\r
}\r
*q = NULLCHAR;\r
*(int *) ad->argLoc = atoi(argValue);\r
break;\r
\r
+ case ArgX:\r
+ *(int *) ad->argLoc = atoi(argValue) + boardX; // [HGM] placement: translate stored relative to absolute\r
+ break;\r
+\r
+ case ArgY:\r
+ *(int *) ad->argLoc = atoi(argValue) + boardY; // (this is really kludgey, it should be done where used...)\r
+ break;\r
+\r
+ case ArgZ:\r
+ *(int *) ad->argLoc = atoi(argValue);\r
+ EnsureOnScreen(&boardX, &boardY, minX, minY);\r
+ break;\r
+\r
case ArgFloat:\r
*(float *) ad->argLoc = (float) atof(argValue);\r
break;\r
\r
case ArgSettingsFilename:\r
{\r
- char fullname[MSG_SIZ];\r
- if (ParseSettingsFile(argValue, fullname)) {\r
- if (ad->argLoc != NULL) {\r
- *(char **) ad->argLoc = strdup(fullname);\r
- }\r
- } else {\r
- if (ad->argLoc != NULL) {\r
- } else {\r
- ExitArgError("Failed to open indirection file", argValue);\r
- }\r
- }\r
+ char fullname[MSG_SIZ];\r
+ if (ParseSettingsFile(argValue, fullname)) {\r
+ if (ad->argLoc != NULL) {\r
+ *(char **) ad->argLoc = strdup(fullname);\r
+ }\r
+ } else {\r
+ if (ad->argLoc != NULL) {\r
+ } else {\r
+ ExitArgError("Failed to open indirection file", argValue);\r
+ }\r
+ }\r
}\r
break;\r
\r
switch (argValue[0]) {\r
case 't':\r
case 'T':\r
- *(Boolean *) ad->argLoc = TRUE;\r
- break;\r
+ *(Boolean *) ad->argLoc = TRUE;\r
+ break;\r
case 'f':\r
case 'F':\r
- *(Boolean *) ad->argLoc = FALSE;\r
- break;\r
+ *(Boolean *) ad->argLoc = FALSE;\r
+ break;\r
default:\r
- ExitArgError("Unrecognized boolean argument value", argValue);\r
- break;\r
+ ExitArgError("Unrecognized boolean argument value", argValue);\r
+ break;\r
}\r
break;\r
\r
ParseAttribs(&textAttribs[cc].color, &textAttribs[cc].effects, argValue);\r
}\r
break;\r
- \r
+\r
case ArgBoardSize:\r
*(BoardSize *)ad->argLoc = ParseBoardSize(argValue);\r
break;\r
case ArgNone:\r
ExitArgError("Unrecognized argument", argValue);\r
break;\r
+ case ArgTrue:\r
+ case ArgFalse: ;\r
}\r
}\r
}\r
{\r
ColorClass cc;\r
for (cc = (ColorClass)0; cc < NColorClasses; cc++) {\r
- ParseAttribs(&textAttribs[cc].color, \r
- &textAttribs[cc].effects, \r
- defaultTextAttribs[cc]);\r
+ ParseAttribs(&textAttribs[cc].color,\r
+ &textAttribs[cc].effects,\r
+ defaultTextAttribs[cc]);\r
}\r
}\r
\r
appData.reuseFirst = TRUE;\r
appData.reuseSecond = TRUE;\r
appData.blindfold = FALSE;\r
+ appData.icsEngineAnalyze = FALSE;\r
+ memset(&dcb, 0, sizeof(DCB)); // required by VS 2002 +\r
dcb.DCBlength = sizeof(DCB);\r
dcb.BaudRate = 9600;\r
dcb.fBinary = TRUE;\r
dcb.fNull = FALSE;\r
dcb.fRtsControl = RTS_CONTROL_ENABLE;\r
dcb.fAbortOnError = FALSE;\r
- dcb.wReserved = 0;\r
dcb.ByteSize = 7;\r
dcb.Parity = SPACEPARITY;\r
dcb.StopBits = ONESTOPBIT;\r
saveSettingsOnExit = TRUE;\r
boardX = CW_USEDEFAULT;\r
boardY = CW_USEDEFAULT;\r
- consoleX = CW_USEDEFAULT; \r
- consoleY = CW_USEDEFAULT; \r
- consoleW = CW_USEDEFAULT;\r
- consoleH = CW_USEDEFAULT;\r
- analysisX = CW_USEDEFAULT; \r
- analysisY = CW_USEDEFAULT; \r
+ analysisX = CW_USEDEFAULT;\r
+ analysisY = CW_USEDEFAULT;\r
analysisW = CW_USEDEFAULT;\r
analysisH = CW_USEDEFAULT;\r
- commentX = CW_USEDEFAULT; \r
- commentY = CW_USEDEFAULT; \r
+ commentX = CW_USEDEFAULT;\r
+ commentY = CW_USEDEFAULT;\r
commentW = CW_USEDEFAULT;\r
commentH = CW_USEDEFAULT;\r
- editTagsX = CW_USEDEFAULT; \r
- editTagsY = CW_USEDEFAULT; \r
+ editTagsX = CW_USEDEFAULT;\r
+ editTagsY = CW_USEDEFAULT;\r
editTagsW = CW_USEDEFAULT;\r
editTagsH = CW_USEDEFAULT;\r
- gameListX = CW_USEDEFAULT; \r
- gameListY = CW_USEDEFAULT; \r
- gameListW = CW_USEDEFAULT;\r
- gameListH = CW_USEDEFAULT;\r
icsTextMenuString = ICS_TEXT_MENU_DEFAULT;\r
icsNames = ICS_NAMES;\r
firstChessProgramNames = FCP_NAMES;\r
appData.firstProtocolVersion = PROTOVER;\r
appData.secondProtocolVersion = PROTOVER;\r
appData.showButtonBar = TRUE;\r
+\r
+ /* [AS] New properties (see comments in header file) */\r
+ appData.firstScoreIsAbsolute = FALSE;\r
+ appData.secondScoreIsAbsolute = FALSE;\r
+ appData.saveExtendedInfoInPGN = FALSE;\r
+ appData.hideThinkingFromHuman = FALSE;\r
+ appData.liteBackTextureFile = "";\r
+ appData.liteBackTextureMode = BACK_TEXTURE_MODE_PLAIN;\r
+ appData.darkBackTextureFile = "";\r
+ appData.darkBackTextureMode = BACK_TEXTURE_MODE_PLAIN;\r
+ appData.renderPiecesWithFont = "";\r
+ appData.fontToPieceTable = "";\r
+ appData.fontBackColorWhite = 0;\r
+ appData.fontForeColorWhite = 0;\r
+ appData.fontBackColorBlack = 0;\r
+ appData.fontForeColorBlack = 0;\r
+ appData.fontPieceSize = 80;\r
+ appData.overrideLineGap = 1;\r
+ appData.adjudicateLossThreshold = 0;\r
+ appData.delayBeforeQuit = 0;\r
+ appData.delayAfterQuit = 0;\r
+ appData.nameOfDebugFile = "winboard.debug";\r
+ appData.pgnEventHeader = "Computer Chess Game";\r
+ appData.defaultFrcPosition = -1;\r
+ appData.gameListTags = GLT_DEFAULT_TAGS;\r
+ appData.saveOutOfBookInfo = TRUE;\r
+ appData.showEvalInMoveHistory = TRUE;\r
+ appData.evalHistColorWhite = ParseColorName( "#FFFFB0" );\r
+ appData.evalHistColorBlack = ParseColorName( "#AD5D3D" );\r
+ appData.highlightMoveWithArrow = FALSE;\r
+ appData.highlightArrowColor = ParseColorName( "#FFFF80" );\r
+ appData.useStickyWindows = TRUE;\r
+ appData.adjudicateDrawMoves = 0;\r
+ appData.autoDisplayComment = TRUE;\r
+ appData.autoDisplayTags = TRUE;\r
+ appData.firstIsUCI = FALSE;\r
+ appData.secondIsUCI = FALSE;\r
+ appData.firstHasOwnBookUCI = TRUE;\r
+ appData.secondHasOwnBookUCI = TRUE;\r
+ appData.polyglotDir = "";\r
+ appData.usePolyglotBook = FALSE;\r
+ appData.polyglotBook = "";\r
+ appData.defaultHashSize = 64;\r
+ appData.defaultCacheSizeEGTB = 4;\r
+ appData.defaultPathEGTB = "c:\\egtb";\r
+ appData.firstOptions = "";\r
+ appData.secondOptions = "";\r
+\r
+ InitWindowPlacement( &wpGameList );\r
+ InitWindowPlacement( &wpMoveHistory );\r
+ InitWindowPlacement( &wpEvalGraph );\r
+ InitWindowPlacement( &wpEngineOutput );\r
+ InitWindowPlacement( &wpConsole );\r
+\r
+ /* [HGM] User-selectable board size, adjudication control, miscellaneous */\r
+ appData.NrFiles = -1;\r
+ appData.NrRanks = -1;\r
+ appData.holdingsSize = -1;\r
+ appData.testClaims = FALSE;\r
+ appData.checkMates = FALSE;\r
+ appData.materialDraws= FALSE;\r
+ appData.trivialDraws = FALSE;\r
+ appData.ruleMoves = 51;\r
+ appData.drawRepeats = 6;\r
+ appData.matchPause = 10000;\r
+ appData.alphaRank = FALSE;\r
+ appData.allWhite = FALSE;\r
+ appData.upsideDown = FALSE;\r
+ appData.serverPause = 15;\r
+ appData.serverMovesName = NULL;\r
+ appData.suppressLoadMoves = FALSE;\r
+ appData.firstTimeOdds = 1;\r
+ appData.secondTimeOdds = 1;\r
+ appData.firstAccumulateTC = 1; // combine previous and current sessions\r
+ appData.secondAccumulateTC = 1;\r
+ appData.firstNPS = -1; // [HGM] nps: use wall-clock time\r
+ appData.secondNPS = -1;\r
+ appData.engineComments = 1;\r
+ appData.smpCores = 1; // [HGM] SMP: max nr of cores\r
+ appData.egtFormats = "";\r
+\r
#ifdef ZIPPY\r
appData.zippyTalk = ZIPPY_TALK;\r
appData.zippyPlay = ZIPPY_PLAY;\r
ParseFontName(font[j][i]->def, &font[j][i]->mfp);\r
}\r
}\r
- \r
+\r
/* Parse default settings file if any */\r
if (ParseSettingsFile(settingsFileName, buf)) {\r
settingsFileName = strdup(buf);\r
/* Parse command line */\r
ParseArgs(StringGet, &lpCmdLine);\r
\r
+ /* [HGM] make sure board size is acceptable */\r
+ if(appData.NrFiles > BOARD_SIZE ||\r
+ appData.NrRanks > BOARD_SIZE )\r
+ DisplayFatalError("Recompile with BOARD_SIZE > 12, to support this size", 0, 2);\r
+\r
+ /* [HGM] After parsing the options from the .ini file, and overruling them\r
+ * with options from the command line, we now make an even higher priority\r
+ * overrule by WB options attached to the engine command line. This so that\r
+ * tournament managers can use WB options (such as /timeOdds) that follow\r
+ * the engines.\r
+ */\r
+ if(appData.firstChessProgram != NULL) {\r
+ char *p = StrStr(appData.firstChessProgram, "WBopt");\r
+ static char *f = "first";\r
+ char buf[MSG_SIZ], *q = buf;\r
+ if(p != NULL) { // engine command line contains WinBoard options\r
+ sprintf(buf, p+6, f, f, f, f, f, f, f, f, f, f); // replace %s in them by "first"\r
+ ParseArgs(StringGet, &q);\r
+ p[-1] = 0; // cut them offengine command line\r
+ }\r
+ }\r
+ // now do same for second chess program\r
+ if(appData.secondChessProgram != NULL) {\r
+ char *p = StrStr(appData.secondChessProgram, "WBopt");\r
+ static char *s = "second";\r
+ char buf[MSG_SIZ], *q = buf;\r
+ if(p != NULL) { // engine command line contains WinBoard options\r
+ sprintf(buf, p+6, s, s, s, s, s, s, s, s, s, s); // replace %s in them by "first"\r
+ ParseArgs(StringGet, &q);\r
+ p[-1] = 0; // cut them offengine command line\r
+ }\r
+ }\r
+\r
+\r
/* Propagate options that affect others */\r
if (appData.matchMode || appData.matchGames) chessProgram = TRUE;\r
if (appData.icsActive || appData.noChessProgram) {\r
(chessProgram && (*appData.firstChessProgram == NULLCHAR ||\r
*appData.secondChessProgram == NULLCHAR))) {\r
FARPROC lpProc;\r
- \r
+\r
lpProc = MakeProcInstance((FARPROC)StartupDialog, hInst);\r
DialogBox(hInst, MAKEINTRESOURCE(DLG_Startup), NULL, (DLGPROC)lpProc);\r
FreeProcInstance(lpProc);\r
HMENU hmenu = GetMenu(hwndMain);\r
\r
(void) EnableMenuItem(hmenu, IDM_CommPort,\r
- MF_BYCOMMAND|((appData.icsActive &&\r
- *appData.icsCommPort != NULLCHAR) ?\r
- MF_ENABLED : MF_GRAYED));\r
+ MF_BYCOMMAND|((appData.icsActive &&\r
+ *appData.icsCommPort != NULLCHAR) ?\r
+ MF_ENABLED : MF_GRAYED));\r
(void) CheckMenuItem(hmenu, IDM_SaveSettingsOnExit,\r
- MF_BYCOMMAND|(saveSettingsOnExit ?\r
- MF_CHECKED : MF_UNCHECKED));\r
+ MF_BYCOMMAND|(saveSettingsOnExit ?\r
+ MF_CHECKED : MF_UNCHECKED));\r
}\r
\r
\r
return;\r
}\r
fprintf(f, ";\n");\r
- fprintf(f, "; %s %s.%s Save Settings file\n", PRODUCT, VERSION, PATCHLEVEL);\r
+ fprintf(f, "; %s Save Settings file\n", PACKAGE_STRING);\r
fprintf(f, ";\n");\r
fprintf(f, "; You can edit the values of options that are already set in this file,\n");\r
fprintf(f, "; but if you add other options, the next Save Settings will not save them.\n");\r
\r
if (hwndConsole) {\r
GetWindowPlacement(hwndConsole, &wp);\r
- consoleX = wp.rcNormalPosition.left;\r
- consoleY = wp.rcNormalPosition.top;\r
- consoleW = wp.rcNormalPosition.right - wp.rcNormalPosition.left;\r
- consoleH = wp.rcNormalPosition.bottom - wp.rcNormalPosition.top;\r
+ wpConsole.x = wp.rcNormalPosition.left;\r
+ wpConsole.y = wp.rcNormalPosition.top;\r
+ wpConsole.width = wp.rcNormalPosition.right - wp.rcNormalPosition.left;\r
+ wpConsole.height = wp.rcNormalPosition.bottom - wp.rcNormalPosition.top;\r
}\r
\r
if (analysisDialog) {\r
\r
if (gameListDialog) {\r
GetWindowPlacement(gameListDialog, &wp);\r
- gameListX = wp.rcNormalPosition.left;\r
- gameListY = wp.rcNormalPosition.top;\r
- gameListW = wp.rcNormalPosition.right - wp.rcNormalPosition.left;\r
- gameListH = wp.rcNormalPosition.bottom - wp.rcNormalPosition.top;\r
+ wpGameList.x = wp.rcNormalPosition.left;\r
+ wpGameList.y = wp.rcNormalPosition.top;\r
+ wpGameList.width = wp.rcNormalPosition.right - wp.rcNormalPosition.left;\r
+ wpGameList.height = wp.rcNormalPosition.bottom - wp.rcNormalPosition.top;\r
+ }\r
+\r
+ /* [AS] Move history */\r
+ wpMoveHistory.visible = MoveHistoryIsUp();\r
+\r
+ if( moveHistoryDialog ) {\r
+ GetWindowPlacement(moveHistoryDialog, &wp);\r
+ wpMoveHistory.x = wp.rcNormalPosition.left;\r
+ wpMoveHistory.y = wp.rcNormalPosition.top;\r
+ wpMoveHistory.width = wp.rcNormalPosition.right - wp.rcNormalPosition.left;\r
+ wpMoveHistory.height = wp.rcNormalPosition.bottom - wp.rcNormalPosition.top;\r
+ }\r
+\r
+ /* [AS] Eval graph */\r
+ wpEvalGraph.visible = EvalGraphIsUp();\r
+\r
+ if( evalGraphDialog ) {\r
+ GetWindowPlacement(evalGraphDialog, &wp);\r
+ wpEvalGraph.x = wp.rcNormalPosition.left;\r
+ wpEvalGraph.y = wp.rcNormalPosition.top;\r
+ wpEvalGraph.width = wp.rcNormalPosition.right - wp.rcNormalPosition.left;\r
+ wpEvalGraph.height = wp.rcNormalPosition.bottom - wp.rcNormalPosition.top;\r
+ }\r
+\r
+ /* [AS] Engine output */\r
+ wpEngineOutput.visible = EngineOutputIsUp();\r
+\r
+ if( engineOutputDialog ) {\r
+ GetWindowPlacement(engineOutputDialog, &wp);\r
+ wpEngineOutput.x = wp.rcNormalPosition.left;\r
+ wpEngineOutput.y = wp.rcNormalPosition.top;\r
+ wpEngineOutput.width = wp.rcNormalPosition.right - wp.rcNormalPosition.left;\r
+ wpEngineOutput.height = wp.rcNormalPosition.bottom - wp.rcNormalPosition.top;\r
}\r
\r
for (ad = argDescriptors; ad->argName != NULL; ad++) {\r
switch (ad->argType) {\r
case ArgString:\r
{\r
- char *p = *(char **)ad->argLoc;\r
- if ((strchr(p, '\\') || strchr(p, '\n')) && !strchr(p, '}')) {\r
- /* Quote multiline values or \-containing values\r
- with { } if possible */\r
- fprintf(f, "/%s={%s}\n", ad->argName, p);\r
- } else {\r
- /* Else quote with " " */\r
- fprintf(f, "/%s=\"", ad->argName);\r
- while (*p) {\r
- if (*p == '\n') fprintf(f, "\n");\r
- else if (*p == '\r') fprintf(f, "\\r");\r
- else if (*p == '\t') fprintf(f, "\\t");\r
- else if (*p == '\b') fprintf(f, "\\b");\r
- else if (*p == '\f') fprintf(f, "\\f");\r
- else if (*p < ' ') fprintf(f, "\\%03o", *p);\r
- else if (*p == '\"') fprintf(f, "\\\"");\r
- else if (*p == '\\') fprintf(f, "\\\\");\r
- else putc(*p, f);\r
- p++;\r
- }\r
- fprintf(f, "\"\n");\r
- }\r
+ char *p = *(char **)ad->argLoc;\r
+ if ((strchr(p, '\\') || strchr(p, '\n')) && !strchr(p, '}')) {\r
+ /* Quote multiline values or \-containing values\r
+ with { } if possible */\r
+ fprintf(f, "/%s={%s}\n", ad->argName, p);\r
+ } else {\r
+ /* Else quote with " " */\r
+ fprintf(f, "/%s=\"", ad->argName);\r
+ while (*p) {\r
+ if (*p == '\n') fprintf(f, "\n");\r
+ else if (*p == '\r') fprintf(f, "\\r");\r
+ else if (*p == '\t') fprintf(f, "\\t");\r
+ else if (*p == '\b') fprintf(f, "\\b");\r
+ else if (*p == '\f') fprintf(f, "\\f");\r
+ else if (*p < ' ') fprintf(f, "\\%03o", *p);\r
+ else if (*p == '\"') fprintf(f, "\\\"");\r
+ else if (*p == '\\') fprintf(f, "\\\\");\r
+ else putc(*p, f);\r
+ p++;\r
+ }\r
+ fprintf(f, "\"\n");\r
+ }\r
}\r
break;\r
case ArgInt:\r
+ case ArgZ:\r
fprintf(f, "/%s=%d\n", ad->argName, *(int *)ad->argLoc);\r
break;\r
+ case ArgX:\r
+ fprintf(f, "/%s=%d\n", ad->argName, *(int *)ad->argLoc - boardX); // [HGM] placement: stor relative value\r
+ break;\r
+ case ArgY:\r
+ fprintf(f, "/%s=%d\n", ad->argName, *(int *)ad->argLoc - boardY);\r
+ break;\r
case ArgFloat:\r
fprintf(f, "/%s=%g\n", ad->argName, *(float *)ad->argLoc);\r
break;\r
case ArgBoolean:\r
- fprintf(f, "/%s=%s\n", ad->argName, \r
- (*(Boolean *)ad->argLoc) ? "true" : "false");\r
+ fprintf(f, "/%s=%s\n", ad->argName,\r
+ (*(Boolean *)ad->argLoc) ? "true" : "false");\r
break;\r
case ArgTrue:\r
if (*(Boolean *)ad->argLoc) fprintf(f, "/%s\n", ad->argName);\r
break;\r
case ArgColor:\r
{\r
- COLORREF color = *(COLORREF *)ad->argLoc;\r
- fprintf(f, "/%s=#%02x%02x%02x\n", ad->argName, \r
- color&0xff, (color>>8)&0xff, (color>>16)&0xff);\r
+ COLORREF color = *(COLORREF *)ad->argLoc;\r
+ fprintf(f, "/%s=#%02lx%02lx%02lx\n", ad->argName,\r
+ color&0xff, (color>>8)&0xff, (color>>16)&0xff);\r
}\r
break;\r
case ArgAttribs:\r
{\r
- MyTextAttribs* ta = &textAttribs[(ColorClass)ad->argLoc];\r
- fprintf(f, "/%s=\"%s%s%s%s%s#%02x%02x%02x\"\n", ad->argName,\r
+ MyTextAttribs* ta = &textAttribs[(ColorClass)ad->argLoc];\r
+ fprintf(f, "/%s=\"%s%s%s%s%s#%02lx%02lx%02lx\"\n", ad->argName,\r
(ta->effects & CFE_BOLD) ? "b" : "",\r
(ta->effects & CFE_ITALIC) ? "i" : "",\r
(ta->effects & CFE_UNDERLINE) ? "u" : "",\r
(ta->effects & CFE_STRIKEOUT) ? "s" : "",\r
(ta->effects) ? " " : "",\r
- ta->color&0xff, (ta->color >> 8)&0xff, (ta->color >> 16)&0xff);\r
+ ta->color&0xff, (ta->color >> 8)&0xff, (ta->color >> 16)&0xff);\r
}\r
break;\r
case ArgFilename:\r
if (strchr(*(char **)ad->argLoc, '\"')) {\r
- fprintf(f, "/%s='%s'\n", ad->argName, *(char **)ad->argLoc);\r
+ fprintf(f, "/%s='%s'\n", ad->argName, *(char **)ad->argLoc);\r
} else {\r
- fprintf(f, "/%s=\"%s\"\n", ad->argName, *(char **)ad->argLoc);\r
+ fprintf(f, "/%s=\"%s\"\n", ad->argName, *(char **)ad->argLoc);\r
}\r
break;\r
case ArgBoardSize:\r
fprintf(f, "/%s=%s\n", ad->argName,\r
- sizeInfo[*(BoardSize *)ad->argLoc].name);\r
+ sizeInfo[*(BoardSize *)ad->argLoc].name);\r
break;\r
case ArgFont:\r
{\r
int bs;\r
- for (bs=0; bs<NUM_SIZES; bs++) {\r
- MyFontParams *mfp = &font[bs][(int) ad->argLoc]->mfp;\r
+ for (bs=0; bs<NUM_SIZES; bs++) {\r
+ MyFontParams *mfp = &font[bs][(int) ad->argLoc]->mfp;\r
fprintf(f, "/size=%s ", sizeInfo[bs].name);\r
- fprintf(f, "/%s=\"%s:%g%s%s%s%s%s\"\n",\r
- ad->argName, mfp->faceName, mfp->pointSize,\r
+ fprintf(f, "/%s=\"%s:%g%s%s%s%s%s\"\n",\r
+ ad->argName, mfp->faceName, mfp->pointSize,\r
mfp->bold || mfp->italic || mfp->underline || mfp->strikeout ? " " : "",\r
- mfp->bold ? "b" : "",\r
- mfp->italic ? "i" : "",\r
- mfp->underline ? "u" : "",\r
- mfp->strikeout ? "s" : "");\r
- }\r
+ mfp->bold ? "b" : "",\r
+ mfp->italic ? "i" : "",\r
+ mfp->underline ? "u" : "",\r
+ mfp->strikeout ? "s" : "");\r
+ }\r
}\r
break;\r
case ArgCommSettings:\r
PrintCommSettings(f, ad->argName, (DCB *)ad->argLoc);\r
+ case ArgNone:\r
+ case ArgSettingsFilename: ;\r
}\r
}\r
fclose(f);\r
*\r
\*---------------------------------------------------------------------------*/\r
\r
+/* [AS] Draw square using background texture */\r
+static void DrawTile( int dx, int dy, int dw, int dh, HDC dst, HDC src, int mode, int sx, int sy )\r
+{\r
+ XFORM x;\r
+\r
+ if( mode == 0 ) {\r
+ return; /* Should never happen! */\r
+ }\r
+\r
+ SetGraphicsMode( dst, GM_ADVANCED );\r
+\r
+ switch( mode ) {\r
+ case 1:\r
+ /* Identity */\r
+ break;\r
+ case 2:\r
+ /* X reflection */\r
+ x.eM11 = -1.0;\r
+ x.eM12 = 0;\r
+ x.eM21 = 0;\r
+ x.eM22 = 1.0;\r
+ x.eDx = (FLOAT) dw + dx - 1;\r
+ x.eDy = 0;\r
+ dx = 0;\r
+ SetWorldTransform( dst, &x );\r
+ break;\r
+ case 3:\r
+ /* Y reflection */\r
+ x.eM11 = 1.0;\r
+ x.eM12 = 0;\r
+ x.eM21 = 0;\r
+ x.eM22 = -1.0;\r
+ x.eDx = 0;\r
+ x.eDy = (FLOAT) dh + dy - 1;\r
+ dy = 0;\r
+ SetWorldTransform( dst, &x );\r
+ break;\r
+ case 4:\r
+ /* X/Y flip */\r
+ x.eM11 = 0;\r
+ x.eM12 = 1.0;\r
+ x.eM21 = 1.0;\r
+ x.eM22 = 0;\r
+ x.eDx = (FLOAT) dx;\r
+ x.eDy = (FLOAT) dy;\r
+ dx = 0;\r
+ dy = 0;\r
+ SetWorldTransform( dst, &x );\r
+ break;\r
+ }\r
+\r
+ BitBlt( dst, dx, dy, dw, dh, src, sx, sy, SRCCOPY );\r
+\r
+ x.eM11 = 1.0;\r
+ x.eM12 = 0;\r
+ x.eM21 = 0;\r
+ x.eM22 = 1.0;\r
+ x.eDx = 0;\r
+ x.eDy = 0;\r
+ SetWorldTransform( dst, &x );\r
+\r
+ ModifyWorldTransform( dst, 0, MWT_IDENTITY );\r
+}\r
+\r
+/* [AS] [HGM] Make room for more piece types, so all pieces can be different */\r
+enum {\r
+ PM_WP = (int) WhitePawn,\r
+ PM_WN = (int) WhiteKnight,\r
+ PM_WB = (int) WhiteBishop,\r
+ PM_WR = (int) WhiteRook,\r
+ PM_WQ = (int) WhiteQueen,\r
+ PM_WF = (int) WhiteFerz,\r
+ PM_WW = (int) WhiteWazir,\r
+ PM_WE = (int) WhiteAlfil,\r
+ PM_WM = (int) WhiteMan,\r
+ PM_WO = (int) WhiteCannon,\r
+ PM_WU = (int) WhiteUnicorn,\r
+ PM_WH = (int) WhiteNightrider,\r
+ PM_WA = (int) WhiteAngel,\r
+ PM_WC = (int) WhiteMarshall,\r
+ PM_WAB = (int) WhiteCardinal,\r
+ PM_WD = (int) WhiteDragon,\r
+ PM_WL = (int) WhiteLance,\r
+ PM_WS = (int) WhiteCobra,\r
+ PM_WV = (int) WhiteFalcon,\r
+ PM_WSG = (int) WhiteSilver,\r
+ PM_WG = (int) WhiteGrasshopper,\r
+ PM_WK = (int) WhiteKing,\r
+ PM_BP = (int) BlackPawn,\r
+ PM_BN = (int) BlackKnight,\r
+ PM_BB = (int) BlackBishop,\r
+ PM_BR = (int) BlackRook,\r
+ PM_BQ = (int) BlackQueen,\r
+ PM_BF = (int) BlackFerz,\r
+ PM_BW = (int) BlackWazir,\r
+ PM_BE = (int) BlackAlfil,\r
+ PM_BM = (int) BlackMan,\r
+ PM_BO = (int) BlackCannon,\r
+ PM_BU = (int) BlackUnicorn,\r
+ PM_BH = (int) BlackNightrider,\r
+ PM_BA = (int) BlackAngel,\r
+ PM_BC = (int) BlackMarshall,\r
+ PM_BG = (int) BlackGrasshopper,\r
+ PM_BAB = (int) BlackCardinal,\r
+ PM_BD = (int) BlackDragon,\r
+ PM_BL = (int) BlackLance,\r
+ PM_BS = (int) BlackCobra,\r
+ PM_BV = (int) BlackFalcon,\r
+ PM_BSG = (int) BlackSilver,\r
+ PM_BK = (int) BlackKing\r
+};\r
+\r
+static HFONT hPieceFont = NULL;\r
+static HBITMAP hPieceMask[(int) EmptySquare];\r
+static HBITMAP hPieceFace[(int) EmptySquare];\r
+static int fontBitmapSquareSize = 0;\r
+static char pieceToFontChar[(int) EmptySquare] =\r
+ { 'p', 'n', 'b', 'r', 'q',\r
+ 'n', 'b', 'p', 'n', 'b', 'r', 'b', 'r', 'q', 'k',\r
+ 'k', 'o', 'm', 'v', 't', 'w',\r
+ 'v', 't', 'o', 'm', 'v', 't', 'v', 't', 'w', 'l',\r
+ 'l' };\r
+\r
+extern BOOL SetCharTable( char *table, const char * map );\r
+/* [HGM] moved to backend.c */\r
+\r
+static void SetPieceBackground( HDC hdc, COLORREF color, int mode )\r
+{\r
+ HBRUSH hbrush;\r
+ BYTE r1 = GetRValue( color );\r
+ BYTE g1 = GetGValue( color );\r
+ BYTE b1 = GetBValue( color );\r
+ BYTE r2 = r1 / 2;\r
+ BYTE g2 = g1 / 2;\r
+ BYTE b2 = b1 / 2;\r
+ RECT rc;\r
+\r
+ /* Create a uniform background first */\r
+ hbrush = CreateSolidBrush( color );\r
+ SetRect( &rc, 0, 0, squareSize, squareSize );\r
+ FillRect( hdc, &rc, hbrush );\r
+ DeleteObject( hbrush );\r
+\r
+ if( mode == 1 ) {\r
+ /* Vertical gradient, good for pawn, knight and rook, less for queen and king */\r
+ int steps = squareSize / 2;\r
+ int i;\r
+\r
+ for( i=0; i<steps; i++ ) {\r
+ BYTE r = r1 - (r1-r2) * i / steps;\r
+ BYTE g = g1 - (g1-g2) * i / steps;\r
+ BYTE b = b1 - (b1-b2) * i / steps;\r
+\r
+ hbrush = CreateSolidBrush( RGB(r,g,b) );\r
+ SetRect( &rc, i + squareSize - steps, 0, i + squareSize - steps + 1, squareSize );\r
+ FillRect( hdc, &rc, hbrush );\r
+ DeleteObject(hbrush);\r
+ }\r
+ }\r
+ else if( mode == 2 ) {\r
+ /* Diagonal gradient, good more or less for every piece */\r
+ POINT triangle[3];\r
+ HPEN hpen = SelectObject( hdc, GetStockObject(NULL_PEN) );\r
+ HBRUSH hbrush_old;\r
+ int steps = squareSize;\r
+ int i;\r
+\r
+ triangle[0].x = squareSize - steps;\r
+ triangle[0].y = squareSize;\r
+ triangle[1].x = squareSize;\r
+ triangle[1].y = squareSize;\r
+ triangle[2].x = squareSize;\r
+ triangle[2].y = squareSize - steps;\r
+\r
+ for( i=0; i<steps; i++ ) {\r
+ BYTE r = r1 - (r1-r2) * i / steps;\r
+ BYTE g = g1 - (g1-g2) * i / steps;\r
+ BYTE b = b1 - (b1-b2) * i / steps;\r
+\r
+ hbrush = CreateSolidBrush( RGB(r,g,b) );\r
+ hbrush_old = SelectObject( hdc, hbrush );\r
+ Polygon( hdc, triangle, 3 );\r
+ SelectObject( hdc, hbrush_old );\r
+ DeleteObject(hbrush);\r
+ triangle[0].x++;\r
+ triangle[2].y++;\r
+ }\r
+\r
+ SelectObject( hdc, hpen );\r
+ }\r
+}\r
+\r
+/*\r
+ [AS] The method I use to create the bitmaps it a bit tricky, but it\r
+ seems to work ok. The main problem here is to find the "inside" of a chess\r
+ piece: follow the steps as explained below.\r
+*/\r
+static void CreatePieceMaskFromFont( HDC hdc_window, HDC hdc, int index )\r
+{\r
+ HBITMAP hbm;\r
+ HBITMAP hbm_old;\r
+ COLORREF chroma = RGB(0xFF,0x00,0xFF);\r
+ RECT rc;\r
+ SIZE sz;\r
+ POINT pt;\r
+ int backColor = whitePieceColor;\r
+ int foreColor = blackPieceColor;\r
+\r
+ if( index < (int)BlackPawn && appData.fontBackColorWhite != appData.fontForeColorWhite ) {\r
+ backColor = appData.fontBackColorWhite;\r
+ foreColor = appData.fontForeColorWhite;\r
+ }\r
+ else if( index >= (int)BlackPawn && appData.fontBackColorBlack != appData.fontForeColorBlack ) {\r
+ backColor = appData.fontBackColorBlack;\r
+ foreColor = appData.fontForeColorBlack;\r
+ }\r
+\r
+ /* Mask */\r
+ hbm = CreateCompatibleBitmap( hdc_window, squareSize, squareSize );\r
+\r
+ hbm_old = SelectObject( hdc, hbm );\r
+\r
+ rc.left = 0;\r
+ rc.top = 0;\r
+ rc.right = squareSize;\r
+ rc.bottom = squareSize;\r
+\r
+ /* Step 1: background is now black */\r
+ FillRect( hdc, &rc, GetStockObject(BLACK_BRUSH) );\r
+\r
+ GetTextExtentPoint32( hdc, &pieceToFontChar[index], 1, &sz );\r
+\r
+ pt.x = (squareSize - sz.cx) / 2;\r
+ pt.y = (squareSize - sz.cy) / 2;\r
+\r
+ SetBkMode( hdc, TRANSPARENT );\r
+ SetTextColor( hdc, chroma );\r
+ /* Step 2: the piece has been drawn in purple, there are now black and purple in this bitmap */\r
+ TextOut( hdc, pt.x, pt.y, &pieceToFontChar[appData.allWhite && index >= (int)BlackPawn ? index - (int)BlackPawn : index], 1 );\r
+\r
+ SelectObject( hdc, GetStockObject(WHITE_BRUSH) );\r
+ /* Step 3: the area outside the piece is filled with white */\r
+// FloodFill( hdc, 0, 0, chroma );\r
+ ExtFloodFill( hdc, 0, 0, 0, FLOODFILLSURFACE );\r
+ ExtFloodFill( hdc, 0, squareSize-1, 0, FLOODFILLSURFACE ); // [HGM] fill from all 4 corners, for if piece too big\r
+ ExtFloodFill( hdc, squareSize-1, 0, 0, FLOODFILLSURFACE );\r
+ ExtFloodFill( hdc, squareSize-1, squareSize-1, 0, FLOODFILLSURFACE );\r
+ SelectObject( hdc, GetStockObject(BLACK_BRUSH) );\r
+ /*\r
+ Step 4: this is the tricky part, the area inside the piece is filled with black,\r
+ but if the start point is not inside the piece we're lost!\r
+ There should be a better way to do this... if we could create a region or path\r
+ from the fill operation we would be fine for example.\r
+ */\r
+// FloodFill( hdc, squareSize / 2, squareSize / 2, RGB(0xFF,0xFF,0xFF) );\r
+ ExtFloodFill( hdc, squareSize / 2, squareSize / 2, RGB(0xFF,0xFF,0xFF), FLOODFILLBORDER );\r
+\r
+ { /* [HGM] shave off edges of mask, in an attempt to correct for the fact that FloodFill does not work correctly under Win XP */\r
+ HDC dc2 = CreateCompatibleDC( hdc_window );\r
+ HBITMAP bm2 = CreateCompatibleBitmap( hdc_window, squareSize, squareSize );\r
+\r
+ SelectObject( dc2, bm2 );\r
+ BitBlt( dc2, 0, 0, squareSize, squareSize, hdc, 0, 0, SRCCOPY ); // make copy\r
+ BitBlt( hdc, 0, 1, squareSize-2, squareSize-2, dc2, 1, 1, SRCPAINT );\r
+ BitBlt( hdc, 2, 1, squareSize-2, squareSize-2, dc2, 1, 1, SRCPAINT );\r
+ BitBlt( hdc, 1, 0, squareSize-2, squareSize-2, dc2, 1, 1, SRCPAINT );\r
+ BitBlt( hdc, 1, 2, squareSize-2, squareSize-2, dc2, 1, 1, SRCPAINT );\r
+\r
+ DeleteDC( dc2 );\r
+ DeleteObject( bm2 );\r
+ }\r
+\r
+ SetTextColor( hdc, 0 );\r
+ /*\r
+ Step 5: some fonts have "disconnected" areas that are skipped by the fill:\r
+ draw the piece again in black for safety.\r
+ */\r
+ TextOut( hdc, pt.x, pt.y, &pieceToFontChar[appData.allWhite && index >= (int)BlackPawn ? index - (int)BlackPawn : index], 1 );\r
+\r
+ SelectObject( hdc, hbm_old );\r
+\r
+ if( hPieceMask[index] != NULL ) {\r
+ DeleteObject( hPieceMask[index] );\r
+ }\r
+\r
+ hPieceMask[index] = hbm;\r
+\r
+ /* Face */\r
+ hbm = CreateCompatibleBitmap( hdc_window, squareSize, squareSize );\r
+\r
+ SelectObject( hdc, hbm );\r
+\r
+ {\r
+ HDC dc1 = CreateCompatibleDC( hdc_window );\r
+ HDC dc2 = CreateCompatibleDC( hdc_window );\r
+ HBITMAP bm2 = CreateCompatibleBitmap( hdc_window, squareSize, squareSize );\r
+\r
+ SelectObject( dc1, hPieceMask[index] );\r
+ SelectObject( dc2, bm2 );\r
+ FillRect( dc2, &rc, GetStockObject(WHITE_BRUSH) );\r
+ BitBlt( dc2, 0, 0, squareSize, squareSize, dc1, 0, 0, SRCINVERT );\r
+\r
+ /*\r
+ Now dc2 contains the inverse of the piece mask, i.e. a mask that preserves\r
+ the piece background and deletes (makes transparent) the rest.\r
+ Thanks to that mask, we are free to paint the background with the greates\r
+ freedom, as we'll be able to mask off the unwanted parts when finished.\r
+ We use this, to make gradients and give the pieces a "roundish" look.\r
+ */\r
+ SetPieceBackground( hdc, backColor, 2 );\r
+ BitBlt( hdc, 0, 0, squareSize, squareSize, dc2, 0, 0, SRCAND );\r
+\r
+ DeleteDC( dc2 );\r
+ DeleteDC( dc1 );\r
+ DeleteObject( bm2 );\r
+ }\r
+\r
+ SetTextColor( hdc, foreColor );\r
+ TextOut( hdc, pt.x, pt.y, &pieceToFontChar[appData.allWhite && index >= (int)BlackPawn ? index - (int)BlackPawn : index], 1 );\r
+\r
+ SelectObject( hdc, hbm_old );\r
+\r
+ if( hPieceFace[index] != NULL ) {\r
+ DeleteObject( hPieceFace[index] );\r
+ }\r
+\r
+ hPieceFace[index] = hbm;\r
+}\r
+\r
+static int TranslatePieceToFontPiece( int piece )\r
+{\r
+ switch( piece ) {\r
+ case BlackPawn:\r
+ return PM_BP;\r
+ case BlackKnight:\r
+ return PM_BN;\r
+ case BlackBishop:\r
+ return PM_BB;\r
+ case BlackRook:\r
+ return PM_BR;\r
+ case BlackQueen:\r
+ return PM_BQ;\r
+ case BlackKing:\r
+ return PM_BK;\r
+ case WhitePawn:\r
+ return PM_WP;\r
+ case WhiteKnight:\r
+ return PM_WN;\r
+ case WhiteBishop:\r
+ return PM_WB;\r
+ case WhiteRook:\r
+ return PM_WR;\r
+ case WhiteQueen:\r
+ return PM_WQ;\r
+ case WhiteKing:\r
+ return PM_WK;\r
+\r
+ case BlackAngel:\r
+ return PM_BA;\r
+ case BlackMarshall:\r
+ return PM_BC;\r
+ case BlackFerz:\r
+ return PM_BF;\r
+ case BlackNightrider:\r
+ return PM_BH;\r
+ case BlackAlfil:\r
+ return PM_BE;\r
+ case BlackWazir:\r
+ return PM_BW;\r
+ case BlackUnicorn:\r
+ return PM_BU;\r
+ case BlackCannon:\r
+ return PM_BO;\r
+ case BlackGrasshopper:\r
+ return PM_BG;\r
+ case BlackMan:\r
+ return PM_BM;\r
+ case BlackSilver:\r
+ return PM_BSG;\r
+ case BlackLance:\r
+ return PM_BL;\r
+ case BlackFalcon:\r
+ return PM_BV;\r
+ case BlackCobra:\r
+ return PM_BS;\r
+ case BlackCardinal:\r
+ return PM_BAB;\r
+ case BlackDragon:\r
+ return PM_BD;\r
+\r
+ case WhiteAngel:\r
+ return PM_WA;\r
+ case WhiteMarshall:\r
+ return PM_WC;\r
+ case WhiteFerz:\r
+ return PM_WF;\r
+ case WhiteNightrider:\r
+ return PM_WH;\r
+ case WhiteAlfil:\r
+ return PM_WE;\r
+ case WhiteWazir:\r
+ return PM_WW;\r
+ case WhiteUnicorn:\r
+ return PM_WU;\r
+ case WhiteCannon:\r
+ return PM_WO;\r
+ case WhiteGrasshopper:\r
+ return PM_WG;\r
+ case WhiteMan:\r
+ return PM_WM;\r
+ case WhiteSilver:\r
+ return PM_WSG;\r
+ case WhiteLance:\r
+ return PM_WL;\r
+ case WhiteFalcon:\r
+ return PM_WV;\r
+ case WhiteCobra:\r
+ return PM_WS;\r
+ case WhiteCardinal:\r
+ return PM_WAB;\r
+ case WhiteDragon:\r
+ return PM_WD;\r
+ }\r
+\r
+ return 0;\r
+}\r
+\r
+void CreatePiecesFromFont()\r
+{\r
+ LOGFONT lf;\r
+ HDC hdc_window = NULL;\r
+ HDC hdc = NULL;\r
+ HFONT hfont_old;\r
+ int fontHeight;\r
+ int i;\r
+\r
+ if( fontBitmapSquareSize < 0 ) {\r
+ /* Something went seriously wrong in the past: do not try to recreate fonts! */\r
+ return;\r
+ }\r
+\r
+ if( appData.renderPiecesWithFont == NULL || appData.renderPiecesWithFont[0] == NULLCHAR || appData.renderPiecesWithFont[0] == '*' ) {\r
+ fontBitmapSquareSize = -1;\r
+ return;\r
+ }\r
+\r
+ if( fontBitmapSquareSize != squareSize ) {\r
+ hdc_window = GetDC( hwndMain );\r
+ hdc = CreateCompatibleDC( hdc_window );\r
+\r
+ if( hPieceFont != NULL ) {\r
+ DeleteObject( hPieceFont );\r
+ }\r
+ else {\r
+ for( i=0; i<=(int)BlackKing; i++ ) {\r
+ hPieceMask[i] = NULL;\r
+ hPieceFace[i] = NULL;\r
+ }\r
+ }\r
+\r
+ fontHeight = 75;\r
+\r
+ if( appData.fontPieceSize >= 50 && appData.fontPieceSize <= 150 ) {\r
+ fontHeight = appData.fontPieceSize;\r
+ }\r
+\r
+ fontHeight = (fontHeight * squareSize) / 100;\r
+\r
+ lf.lfHeight = -MulDiv( fontHeight, GetDeviceCaps(hdc, LOGPIXELSY), 72 );\r
+ lf.lfWidth = 0;\r
+ lf.lfEscapement = 0;\r
+ lf.lfOrientation = 0;\r
+ lf.lfWeight = FW_NORMAL;\r
+ lf.lfItalic = 0;\r
+ lf.lfUnderline = 0;\r
+ lf.lfStrikeOut = 0;\r
+ lf.lfCharSet = DEFAULT_CHARSET;\r
+ lf.lfOutPrecision = OUT_DEFAULT_PRECIS;\r
+ lf.lfClipPrecision = CLIP_DEFAULT_PRECIS;\r
+ lf.lfQuality = PROOF_QUALITY;\r
+ lf.lfPitchAndFamily = DEFAULT_PITCH | FF_DONTCARE;\r
+ strncpy( lf.lfFaceName, appData.renderPiecesWithFont, sizeof(lf.lfFaceName) );\r
+ lf.lfFaceName[ sizeof(lf.lfFaceName) - 1 ] = '\0';\r
+\r
+ hPieceFont = CreateFontIndirect( &lf );\r
+\r
+ if( hPieceFont == NULL ) {\r
+ fontBitmapSquareSize = -2;\r
+ }\r
+ else {\r
+ /* Setup font-to-piece character table */\r
+ if( ! SetCharTable(pieceToFontChar, appData.fontToPieceTable) ) {\r
+ /* No (or wrong) global settings, try to detect the font */\r
+ if( strstr(lf.lfFaceName,"Alpha") != NULL ) {\r
+ /* Alpha */\r
+ SetCharTable(pieceToFontChar, "phbrqkojntwl");\r
+ }\r
+ else if( strstr(lf.lfFaceName,"DiagramTT") != NULL ) {\r
+ /* DiagramTT* family */\r
+ SetCharTable(pieceToFontChar, "PNLRQKpnlrqk");\r
+ }\r
+ else if( strstr(lf.lfFaceName,"WinboardF") != NULL ) {\r
+ /* Fairy symbols */\r
+ SetCharTable(pieceToFontChar, "PNBRQFEACWMOHIJGDVSLUKpnbrqfeacwmohijgdvsluk");\r
+ }\r
+ else if( strstr(lf.lfFaceName,"GC2004D") != NULL ) {\r
+ /* Good Companion (Some characters get warped as literal :-( */\r
+ char s[] = "1cmWG0ñueOS¯®oYI23wgQU";\r
+ s[0]=0xB9; s[1]=0xA9; s[6]=0xB1; s[11]=0xBB; s[12]=0xAB; s[17]=0xB3;\r
+ SetCharTable(pieceToFontChar, s);\r
+ }\r
+ else {\r
+ /* Cases, Condal, Leipzig, Lucena, Marroquin, Merida, Usual */\r
+ SetCharTable(pieceToFontChar, "pnbrqkomvtwl");\r
+ }\r
+ }\r
+\r
+ /* Create bitmaps */\r
+ hfont_old = SelectObject( hdc, hPieceFont );\r
+#if 0\r
+ CreatePieceMaskFromFont( hdc_window, hdc, PM_WP );\r
+ CreatePieceMaskFromFont( hdc_window, hdc, PM_WN );\r
+ CreatePieceMaskFromFont( hdc_window, hdc, PM_WB );\r
+ CreatePieceMaskFromFont( hdc_window, hdc, PM_WR );\r
+ CreatePieceMaskFromFont( hdc_window, hdc, PM_WQ );\r
+ CreatePieceMaskFromFont( hdc_window, hdc, PM_WK );\r
+ CreatePieceMaskFromFont( hdc_window, hdc, PM_BP );\r
+ CreatePieceMaskFromFont( hdc_window, hdc, PM_BN );\r
+ CreatePieceMaskFromFont( hdc_window, hdc, PM_BB );\r
+ CreatePieceMaskFromFont( hdc_window, hdc, PM_BR );\r
+ CreatePieceMaskFromFont( hdc_window, hdc, PM_BQ );\r
+ CreatePieceMaskFromFont( hdc_window, hdc, PM_BK );\r
+\r
+ CreatePieceMaskFromFont( hdc_window, hdc, PM_WA );\r
+ CreatePieceMaskFromFont( hdc_window, hdc, PM_WC );\r
+ CreatePieceMaskFromFont( hdc_window, hdc, PM_WF );\r
+ CreatePieceMaskFromFont( hdc_window, hdc, PM_WH );\r
+ CreatePieceMaskFromFont( hdc_window, hdc, PM_WE );\r
+ CreatePieceMaskFromFont( hdc_window, hdc, PM_WW );\r
+ CreatePieceMaskFromFont( hdc_window, hdc, PM_WU );\r
+ CreatePieceMaskFromFont( hdc_window, hdc, PM_WO );\r
+ CreatePieceMaskFromFont( hdc_window, hdc, PM_WG );\r
+ CreatePieceMaskFromFont( hdc_window, hdc, PM_WM );\r
+ CreatePieceMaskFromFont( hdc_window, hdc, PM_WSG );\r
+ CreatePieceMaskFromFont( hdc_window, hdc, PM_WV );\r
+ CreatePieceMaskFromFont( hdc_window, hdc, PM_WAB );\r
+ CreatePieceMaskFromFont( hdc_window, hdc, PM_WD );\r
+ CreatePieceMaskFromFont( hdc_window, hdc, PM_WL );\r
+ CreatePieceMaskFromFont( hdc_window, hdc, PM_WS );\r
+ CreatePieceMaskFromFont( hdc_window, hdc, PM_BA );\r
+ CreatePieceMaskFromFont( hdc_window, hdc, PM_BC );\r
+ CreatePieceMaskFromFont( hdc_window, hdc, PM_BF );\r
+ CreatePieceMaskFromFont( hdc_window, hdc, PM_BH );\r
+ CreatePieceMaskFromFont( hdc_window, hdc, PM_BE );\r
+ CreatePieceMaskFromFont( hdc_window, hdc, PM_BW );\r
+ CreatePieceMaskFromFont( hdc_window, hdc, PM_BU );\r
+ CreatePieceMaskFromFont( hdc_window, hdc, PM_BO );\r
+ CreatePieceMaskFromFont( hdc_window, hdc, PM_BG );\r
+ CreatePieceMaskFromFont( hdc_window, hdc, PM_BM );\r
+ CreatePieceMaskFromFont( hdc_window, hdc, PM_BSG );\r
+ CreatePieceMaskFromFont( hdc_window, hdc, PM_BV );\r
+ CreatePieceMaskFromFont( hdc_window, hdc, PM_BAB );\r
+ CreatePieceMaskFromFont( hdc_window, hdc, PM_BD );\r
+ CreatePieceMaskFromFont( hdc_window, hdc, PM_BL );\r
+ CreatePieceMaskFromFont( hdc_window, hdc, PM_BS );\r
+#else\r
+ for(i=(int)WhitePawn; i<(int)EmptySquare; i++) /* [HGM] made a loop for this */\r
+ if(PieceToChar((ChessSquare)i) != '.') /* skip unused pieces */\r
+ CreatePieceMaskFromFont( hdc_window, hdc, i );\r
+#endif\r
+ SelectObject( hdc, hfont_old );\r
+\r
+ fontBitmapSquareSize = squareSize;\r
+ }\r
+ }\r
+\r
+ if( hdc != NULL ) {\r
+ DeleteDC( hdc );\r
+ }\r
+\r
+ if( hdc_window != NULL ) {\r
+ ReleaseDC( hwndMain, hdc_window );\r
+ }\r
+}\r
+\r
HBITMAP\r
DoLoadBitmap(HINSTANCE hinst, char *piece, int squareSize, char *suffix)\r
{\r
*/\r
pLogPal = (NPLOGPALETTE)\r
LocalAlloc(LMEM_FIXED, (sizeof(LOGPALETTE) +\r
- (sizeof(PALETTEENTRY) * (PALETTESIZE))));\r
+ (sizeof(PALETTEENTRY) * (PALETTESIZE))));\r
pLogPal->palVersion = 0x300;\r
}\r
pLogPal->palNumEntries = 0;\r
hPal = CreatePalette((LPLOGPALETTE) pLogPal);\r
\r
lightSquareBrush = CreateSolidBrush(lightSquareColor);\r
+ blackSquareBrush = CreateSolidBrush(blackPieceColor);\r
darkSquareBrush = CreateSolidBrush(darkSquareColor);\r
whitePieceBrush = CreateSolidBrush(whitePieceColor);\r
blackPieceBrush = CreateSolidBrush(blackPieceColor);\r
iconBkgndBrush = CreateSolidBrush(GetSysColor(COLOR_BACKGROUND));\r
+ explodeBrush = CreateSolidBrush(highlightSquareColor); // [HGM] atomic\r
+ /* [AS] Force rendering of the font-based pieces */\r
+ if( fontBitmapSquareSize > 0 ) {\r
+ fontBitmapSquareSize = 0;\r
+ }\r
}\r
\r
\r
int\r
-BoardWidth(int boardSize)\r
-{\r
- return (BOARD_SIZE + 1) * sizeInfo[boardSize].lineGap +\r
- BOARD_SIZE * sizeInfo[boardSize].squareSize;\r
+BoardWidth(int boardSize, int n)\r
+{ /* [HGM] argument n added to allow different width and height */\r
+ int lineGap = sizeInfo[boardSize].lineGap;\r
+\r
+ if( appData.overrideLineGap >= 0 && appData.overrideLineGap <= 5 ) {\r
+ lineGap = appData.overrideLineGap;\r
+ }\r
+\r
+ return (n + 1) * lineGap +\r
+ n * sizeInfo[boardSize].squareSize;\r
}\r
\r
/* Respond to board resize by dragging edge */\r
if (IsIconic(hwndMain)) return;\r
if (recurse > 0) return;\r
recurse++;\r
- while (newSize > 0 &&\r
- (newSizeX < sizeInfo[newSize].cliWidth ||\r
- newSizeY < sizeInfo[newSize].cliHeight)) {\r
+ while (newSize > 0) {\r
+ InitDrawingSizes(newSize+1000, 0); // [HGM] kludge to update sizeInfo without visible effects\r
+ if(newSizeX >= sizeInfo[newSize].cliWidth &&\r
+ newSizeY >= sizeInfo[newSize].cliHeight) break;\r
newSize--;\r
- } \r
+ }\r
boardSize = newSize;\r
InitDrawingSizes(boardSize, flags);\r
recurse--;\r
VOID\r
InitDrawingSizes(BoardSize boardSize, int flags)\r
{\r
- int i, boardWidth;\r
+ int i, boardWidth, boardHeight; /* [HGM] height treated separately */\r
ChessSquare piece;\r
static int oldBoardSize = -1, oldTinyLayout = 0;\r
HDC hdc;\r
char buf[MSG_SIZ];\r
char *str;\r
HMENU hmenu = GetMenu(hwndMain);\r
- RECT crect, wrect;\r
+ RECT crect, wrect, oldRect;\r
int offby;\r
LOGBRUSH logbrush;\r
\r
+ int suppressVisibleEffects = 0; // [HGM] kludge to request updating sizeInfo only\r
+ if((int)boardSize >= 1000 ) { boardSize -= 1000; suppressVisibleEffects = 1; }\r
+\r
+ /* [HGM] call with -2 uses old size (for if nr of files, ranks changes) */\r
+ if(boardSize == (BoardSize)(-2) ) boardSize = oldBoardSize;\r
+\r
+ oldRect.left = boardX; //[HGM] placement: remember previous window params\r
+ oldRect.top = boardY;\r
+ oldRect.right = boardX + winWidth;\r
+ oldRect.bottom = boardY + winHeight;\r
+\r
tinyLayout = sizeInfo[boardSize].tinyLayout;\r
smallLayout = sizeInfo[boardSize].smallLayout;\r
squareSize = sizeInfo[boardSize].squareSize;\r
lineGap = sizeInfo[boardSize].lineGap;\r
+ minorSize = 0; /* [HGM] Kludge to see if demagnified pieces need to be shifted */\r
+\r
+ if( appData.overrideLineGap >= 0 && appData.overrideLineGap <= 5 ) {\r
+ lineGap = appData.overrideLineGap;\r
+ }\r
\r
if (tinyLayout != oldTinyLayout) {\r
long style = GetWindowLong(hwndMain, GWL_STYLE);\r
if (tinyLayout) {\r
style &= ~WS_SYSMENU;\r
InsertMenu(hmenu, IDM_Exit, MF_BYCOMMAND, IDM_Minimize,\r
- "&Minimize\tCtrl+F4");\r
+ "&Minimize\tCtrl+F4");\r
} else {\r
style |= WS_SYSMENU;\r
RemoveMenu(hmenu, IDM_Minimize, MF_BYCOMMAND);\r
SetWindowLong(hwndMain, GWL_STYLE, style);\r
\r
for (i=0; menuBarText[tinyLayout][i]; i++) {\r
- ModifyMenu(hmenu, i, MF_STRING|MF_BYPOSITION|MF_POPUP, \r
- (UINT)GetSubMenu(hmenu, i), menuBarText[tinyLayout][i]);\r
+ ModifyMenu(hmenu, i, MF_STRING|MF_BYPOSITION|MF_POPUP,\r
+ (UINT)GetSubMenu(hmenu, i), menuBarText[tinyLayout][i]);\r
}\r
DrawMenuBar(hwndMain);\r
}\r
\r
- boardWidth = BoardWidth(boardSize);\r
+ boardWidth = BoardWidth(boardSize, BOARD_WIDTH);\r
+ boardHeight = BoardWidth(boardSize, BOARD_HEIGHT);\r
\r
/* Get text area sizes */\r
hdc = GetDC(hwndMain);\r
ReleaseDC(hwndMain, hdc);\r
\r
/* Compute where everything goes */\r
- whiteRect.left = OUTER_MARGIN;\r
- whiteRect.right = whiteRect.left + boardWidth/2 - INNER_MARGIN/2;\r
- whiteRect.top = OUTER_MARGIN;\r
- whiteRect.bottom = whiteRect.top + clockSize.cy;\r
+ if((first.programLogo || second.programLogo) && !tinyLayout) {\r
+ /* [HGM] logo: if either logo is on, reserve space for it */\r
+ logoHeight = 2*clockSize.cy;\r
+ leftLogoRect.left = OUTER_MARGIN;\r
+ leftLogoRect.right = leftLogoRect.left + 4*clockSize.cy;\r
+ leftLogoRect.top = OUTER_MARGIN;\r
+ leftLogoRect.bottom = OUTER_MARGIN + logoHeight;\r
+\r
+ rightLogoRect.right = OUTER_MARGIN + boardWidth;\r
+ rightLogoRect.left = rightLogoRect.right - 4*clockSize.cy;\r
+ rightLogoRect.top = OUTER_MARGIN;\r
+ rightLogoRect.bottom = OUTER_MARGIN + logoHeight;\r
+\r
+\r
+ whiteRect.left = leftLogoRect.right;\r
+ whiteRect.right = OUTER_MARGIN + boardWidth/2 - INNER_MARGIN/2;\r
+ whiteRect.top = OUTER_MARGIN;\r
+ whiteRect.bottom = whiteRect.top + logoHeight;\r
+\r
+ blackRect.right = rightLogoRect.left;\r
+ blackRect.left = whiteRect.right + INNER_MARGIN;\r
+ blackRect.top = whiteRect.top;\r
+ blackRect.bottom = whiteRect.bottom;\r
+ } else {\r
+ whiteRect.left = OUTER_MARGIN;\r
+ whiteRect.right = whiteRect.left + boardWidth/2 - INNER_MARGIN/2;\r
+ whiteRect.top = OUTER_MARGIN;\r
+ whiteRect.bottom = whiteRect.top + clockSize.cy;\r
\r
- blackRect.left = whiteRect.right + INNER_MARGIN;\r
- blackRect.right = blackRect.left + boardWidth/2 - 1;\r
- blackRect.top = whiteRect.top;\r
- blackRect.bottom = whiteRect.bottom;\r
+ blackRect.left = whiteRect.right + INNER_MARGIN;\r
+ blackRect.right = blackRect.left + boardWidth/2 - 1;\r
+ blackRect.top = whiteRect.top;\r
+ blackRect.bottom = whiteRect.bottom;\r
+ }\r
\r
- messageRect.left = whiteRect.left + MESSAGE_LINE_LEFTMARGIN;\r
+ messageRect.left = OUTER_MARGIN + MESSAGE_LINE_LEFTMARGIN;\r
if (appData.showButtonBar) {\r
- messageRect.right = blackRect.right\r
+ messageRect.right = OUTER_MARGIN + boardWidth // [HGM] logo: expressed independent of clock placement\r
- N_BUTTONS*BUTTON_WIDTH - MESSAGE_LINE_LEFTMARGIN;\r
} else {\r
- messageRect.right = blackRect.right;\r
+ messageRect.right = OUTER_MARGIN + boardWidth;\r
}\r
messageRect.top = whiteRect.bottom + INNER_MARGIN;\r
messageRect.bottom = messageRect.top + messageSize.cy;\r
\r
- boardRect.left = whiteRect.left;\r
+ boardRect.left = OUTER_MARGIN;\r
boardRect.right = boardRect.left + boardWidth;\r
boardRect.top = messageRect.bottom + INNER_MARGIN;\r
- boardRect.bottom = boardRect.top + boardWidth;\r
+ boardRect.bottom = boardRect.top + boardHeight;\r
\r
sizeInfo[boardSize].cliWidth = boardRect.right + OUTER_MARGIN;\r
sizeInfo[boardSize].cliHeight = boardRect.bottom + OUTER_MARGIN;\r
- winWidth = 2 * GetSystemMetrics(SM_CXFRAME) + boardRect.right + OUTER_MARGIN;\r
- winHeight = 2 * GetSystemMetrics(SM_CYFRAME) + GetSystemMetrics(SM_CYMENU) +\r
+ oldBoardSize = boardSize;\r
+ oldTinyLayout = tinyLayout;\r
+ winW = 2 * GetSystemMetrics(SM_CXFRAME) + boardRect.right + OUTER_MARGIN;\r
+ winH = 2 * GetSystemMetrics(SM_CYFRAME) + GetSystemMetrics(SM_CYMENU) +\r
GetSystemMetrics(SM_CYCAPTION) + boardRect.bottom + OUTER_MARGIN;\r
+ if(suppressVisibleEffects) return; // [HGM] when called for filling sizeInfo only\r
+ winWidth = winW; // [HGM] placement: set through temporary which can used by initial sizing choice\r
+ winHeight = winH; // without disturbing window attachments\r
GetWindowRect(hwndMain, &wrect);\r
SetWindowPos(hwndMain, NULL, 0, 0, winWidth, winHeight,\r
- SWP_NOCOPYBITS|SWP_NOZORDER|SWP_NOMOVE);\r
+ SWP_NOCOPYBITS|SWP_NOZORDER|SWP_NOMOVE);\r
+\r
+ // [HGM] placement: let attached windows follow size change.\r
+ ReattachAfterSize( &oldRect, winWidth, winHeight, moveHistoryDialog, &wpMoveHistory );\r
+ ReattachAfterSize( &oldRect, winWidth, winHeight, evalGraphDialog, &wpEvalGraph );\r
+ ReattachAfterSize( &oldRect, winWidth, winHeight, engineOutputDialog, &wpEngineOutput );\r
+ ReattachAfterSize( &oldRect, winWidth, winHeight, gameListDialog, &wpGameList );\r
+ ReattachAfterSize( &oldRect, winWidth, winHeight, hwndConsole, &wpConsole );\r
+\r
/* compensate if menu bar wrapped */\r
GetClientRect(hwndMain, &crect);\r
offby = boardRect.bottom + OUTER_MARGIN - crect.bottom;\r
winHeight += offby;\r
switch (flags) {\r
case WMSZ_TOPLEFT:\r
- SetWindowPos(hwndMain, NULL, \r
- wrect.right - winWidth, wrect.bottom - winHeight, \r
+ SetWindowPos(hwndMain, NULL,\r
+ wrect.right - winWidth, wrect.bottom - winHeight,\r
winWidth, winHeight, SWP_NOCOPYBITS|SWP_NOZORDER);\r
break;\r
\r
case WMSZ_TOPRIGHT:\r
case WMSZ_TOP:\r
- SetWindowPos(hwndMain, NULL, \r
- wrect.left, wrect.bottom - winHeight, \r
+ SetWindowPos(hwndMain, NULL,\r
+ wrect.left, wrect.bottom - winHeight,\r
winWidth, winHeight, SWP_NOCOPYBITS|SWP_NOZORDER);\r
break;\r
\r
case WMSZ_BOTTOMLEFT:\r
case WMSZ_LEFT:\r
- SetWindowPos(hwndMain, NULL, \r
- wrect.right - winWidth, wrect.top, \r
+ SetWindowPos(hwndMain, NULL,\r
+ wrect.right - winWidth, wrect.top,\r
winWidth, winHeight, SWP_NOCOPYBITS|SWP_NOZORDER);\r
break;\r
\r
}\r
if (appData.showButtonBar) {\r
buttonDesc[i].hwnd =\r
- CreateWindow("BUTTON", buttonDesc[i].label,\r
- WS_VISIBLE | WS_CHILD | BS_PUSHBUTTON,\r
- boardRect.right - BUTTON_WIDTH*(N_BUTTONS-i),\r
- messageRect.top, BUTTON_WIDTH, messageSize.cy, hwndMain,\r
- (HMENU) buttonDesc[i].id,\r
- (HINSTANCE) GetWindowLong(hwndMain, GWL_HINSTANCE), NULL);\r
+ CreateWindow("BUTTON", buttonDesc[i].label,\r
+ WS_VISIBLE | WS_CHILD | BS_PUSHBUTTON,\r
+ boardRect.right - BUTTON_WIDTH*(N_BUTTONS-i),\r
+ messageRect.top, BUTTON_WIDTH, messageSize.cy, hwndMain,\r
+ (HMENU) buttonDesc[i].id,\r
+ (HINSTANCE) GetWindowLong(hwndMain, GWL_HINSTANCE), NULL);\r
if (tinyLayout) {\r
- SendMessage(buttonDesc[i].hwnd, WM_SETFONT, \r
- (WPARAM)font[boardSize][MESSAGE_FONT]->hf,\r
- MAKELPARAM(FALSE, 0));\r
+ SendMessage(buttonDesc[i].hwnd, WM_SETFONT,\r
+ (WPARAM)font[boardSize][MESSAGE_FONT]->hf,\r
+ MAKELPARAM(FALSE, 0));\r
}\r
if (buttonDesc[i].id == IDM_Pause)\r
- hwndPause = buttonDesc[i].hwnd;\r
+ hwndPause = buttonDesc[i].hwnd;\r
buttonDesc[i].wndproc = (WNDPROC)\r
- SetWindowLong(buttonDesc[i].hwnd, GWL_WNDPROC, (LONG) ButtonProc);\r
+ SetWindowLong(buttonDesc[i].hwnd, GWL_WNDPROC, (LONG) ButtonProc);\r
}\r
}\r
if (gridPen != NULL) DeleteObject(gridPen);\r
ExtCreatePen(PS_GEOMETRIC|PS_SOLID|PS_ENDCAP_FLAT|PS_JOIN_MITER,\r
lineGap, &logbrush, 0, NULL);\r
\r
- logbrush.lbColor = premoveHighlightColor; \r
+ logbrush.lbColor = premoveHighlightColor;\r
premovePen =\r
ExtCreatePen(PS_GEOMETRIC|PS_SOLID|PS_ENDCAP_FLAT|PS_JOIN_MITER,\r
lineGap, &logbrush, 0, NULL);\r
\r
- for (i = 0; i < BOARD_SIZE + 1; i++) {\r
+ /* [HGM] Loop had to be split in part for vert. and hor. lines */\r
+ for (i = 0; i < BOARD_HEIGHT + 1; i++) {\r
gridEndpoints[i*2].x = boardRect.left + lineGap / 2;\r
- gridEndpoints[i*2 + BOARD_SIZE*2 + 2].y = boardRect.top + lineGap / 2;\r
gridEndpoints[i*2].y = gridEndpoints[i*2 + 1].y =\r
- boardRect.top + lineGap / 2 + (i * (squareSize + lineGap));\r
+ boardRect.top + lineGap / 2 + (i * (squareSize + lineGap));\r
gridEndpoints[i*2 + 1].x = boardRect.left + lineGap / 2 +\r
- BOARD_SIZE * (squareSize + lineGap);\r
- gridEndpoints[i*2 + BOARD_SIZE*2 + 2].x =\r
- gridEndpoints[i*2 + 1 + BOARD_SIZE*2 + 2].x = boardRect.left +\r
- lineGap / 2 + (i * (squareSize + lineGap));\r
- gridEndpoints[i*2 + 1 + BOARD_SIZE*2 + 2].y =\r
- boardRect.top + BOARD_SIZE * (squareSize + lineGap);\r
+ BOARD_WIDTH * (squareSize + lineGap);\r
+ gridVertexCounts[i*2] = gridVertexCounts[i*2 + 1] = 2;\r
+ }\r
+ for (i = 0; i < BOARD_WIDTH + 1; i++) {\r
+ gridEndpoints[i*2 + BOARD_HEIGHT*2 + 2].y = boardRect.top + lineGap / 2;\r
+ gridEndpoints[i*2 + BOARD_HEIGHT*2 + 2].x =\r
+ gridEndpoints[i*2 + 1 + BOARD_HEIGHT*2 + 2].x = boardRect.left +\r
+ lineGap / 2 + (i * (squareSize + lineGap));\r
+ gridEndpoints[i*2 + 1 + BOARD_HEIGHT*2 + 2].y =\r
+ boardRect.top + BOARD_HEIGHT * (squareSize + lineGap);\r
gridVertexCounts[i*2] = gridVertexCounts[i*2 + 1] = 2;\r
}\r
}\r
\r
- if (boardSize == oldBoardSize) return;\r
- oldBoardSize = boardSize;\r
- oldTinyLayout = tinyLayout;\r
+ /* [HGM] Licensing requirement */\r
+#ifdef GOTHIC\r
+ if(gameInfo.variant == VariantGothic) GothicPopUp( GOTHIC, VariantGothic); else\r
+#endif\r
+#ifdef FALCON\r
+ if(gameInfo.variant == VariantFalcon) GothicPopUp( FALCON, VariantFalcon); else\r
+#endif\r
+ GothicPopUp( "", VariantNormal);\r
+\r
+\r
+/* if (boardSize == oldBoardSize) return; [HGM] variant might have changed */\r
\r
/* Load piece bitmaps for this board size */\r
for (i=0; i<=2; i++) {\r
for (piece = WhitePawn;\r
- (int) piece <= (int) WhiteKing;\r
- piece = (ChessSquare) ((int) piece + 1)) {\r
+ (int) piece < (int) BlackPawn;\r
+ piece = (ChessSquare) ((int) piece + 1)) {\r
if (pieceBitmap[i][piece] != NULL)\r
- DeleteObject(pieceBitmap[i][piece]);\r
+ DeleteObject(pieceBitmap[i][piece]);\r
}\r
}\r
\r
+ fontBitmapSquareSize = 0; /* [HGM] render: make sure pieces will be recreated, as we might need others now */\r
+ // Orthodox Chess pieces\r
pieceBitmap[0][WhitePawn] = DoLoadBitmap(hInst, "p", squareSize, "s");\r
pieceBitmap[0][WhiteKnight] = DoLoadBitmap(hInst, "n", squareSize, "s");\r
pieceBitmap[0][WhiteBishop] = DoLoadBitmap(hInst, "b", squareSize, "s");\r
pieceBitmap[0][WhiteRook] = DoLoadBitmap(hInst, "r", squareSize, "s");\r
- pieceBitmap[0][WhiteQueen] = DoLoadBitmap(hInst, "q", squareSize, "s");\r
pieceBitmap[0][WhiteKing] = DoLoadBitmap(hInst, "k", squareSize, "s");\r
pieceBitmap[1][WhitePawn] = DoLoadBitmap(hInst, "p", squareSize, "o");\r
pieceBitmap[1][WhiteKnight] = DoLoadBitmap(hInst, "n", squareSize, "o");\r
pieceBitmap[1][WhiteBishop] = DoLoadBitmap(hInst, "b", squareSize, "o");\r
pieceBitmap[1][WhiteRook] = DoLoadBitmap(hInst, "r", squareSize, "o");\r
- pieceBitmap[1][WhiteQueen] = DoLoadBitmap(hInst, "q", squareSize, "o");\r
pieceBitmap[1][WhiteKing] = DoLoadBitmap(hInst, "k", squareSize, "o");\r
pieceBitmap[2][WhitePawn] = DoLoadBitmap(hInst, "p", squareSize, "w");\r
pieceBitmap[2][WhiteKnight] = DoLoadBitmap(hInst, "n", squareSize, "w");\r
pieceBitmap[2][WhiteBishop] = DoLoadBitmap(hInst, "b", squareSize, "w");\r
pieceBitmap[2][WhiteRook] = DoLoadBitmap(hInst, "r", squareSize, "w");\r
- pieceBitmap[2][WhiteQueen] = DoLoadBitmap(hInst, "q", squareSize, "w");\r
pieceBitmap[2][WhiteKing] = DoLoadBitmap(hInst, "k", squareSize, "w");\r
-\r
+ if( !strcmp(appData.variant, "shogi") && (squareSize==72 || squareSize==49)) {\r
+ // in Shogi, Hijack the unused Queen for Lance\r
+ pieceBitmap[0][WhiteQueen] = DoLoadBitmap(hInst, "l", squareSize, "s");\r
+ pieceBitmap[1][WhiteQueen] = DoLoadBitmap(hInst, "l", squareSize, "o");\r
+ pieceBitmap[2][WhiteQueen] = DoLoadBitmap(hInst, "l", squareSize, "w");\r
+ } else {\r
+ pieceBitmap[0][WhiteQueen] = DoLoadBitmap(hInst, "q", squareSize, "s");\r
+ pieceBitmap[1][WhiteQueen] = DoLoadBitmap(hInst, "q", squareSize, "o");\r
+ pieceBitmap[2][WhiteQueen] = DoLoadBitmap(hInst, "q", squareSize, "w");\r
+ }\r
+\r
+ if(squareSize <= 72 && squareSize >= 33) {\r
+ /* A & C are available in most sizes now */\r
+ if(squareSize != 49 && squareSize != 72 && squareSize != 33) { // Vortex-like\r
+ pieceBitmap[0][WhiteAngel] = DoLoadBitmap(hInst, "a", squareSize, "s");\r
+ pieceBitmap[1][WhiteAngel] = DoLoadBitmap(hInst, "a", squareSize, "o");\r
+ pieceBitmap[2][WhiteAngel] = DoLoadBitmap(hInst, "a", squareSize, "w");\r
+ pieceBitmap[0][WhiteSilver] = DoLoadBitmap(hInst, "cv", squareSize, "s");\r
+ pieceBitmap[1][WhiteSilver] = DoLoadBitmap(hInst, "cv", squareSize, "o");\r
+ pieceBitmap[2][WhiteSilver] = DoLoadBitmap(hInst, "cv", squareSize, "w");\r
+ pieceBitmap[0][WhiteCobra] = DoLoadBitmap(hInst, "cv", squareSize, "s");\r
+ pieceBitmap[1][WhiteCobra] = DoLoadBitmap(hInst, "cv", squareSize, "o");\r
+ pieceBitmap[2][WhiteCobra] = DoLoadBitmap(hInst, "cv", squareSize, "w");\r
+ pieceBitmap[0][WhiteLance] = DoLoadBitmap(hInst, "l", squareSize, "s");\r
+ pieceBitmap[1][WhiteLance] = DoLoadBitmap(hInst, "l", squareSize, "o");\r
+ pieceBitmap[2][WhiteLance] = DoLoadBitmap(hInst, "l", squareSize, "w");\r
+ } else { // Smirf-like\r
+ pieceBitmap[0][WhiteAngel] = DoLoadBitmap(hInst, "aa", squareSize, "s");\r
+ pieceBitmap[1][WhiteAngel] = DoLoadBitmap(hInst, "aa", squareSize, "o");\r
+ pieceBitmap[2][WhiteAngel] = DoLoadBitmap(hInst, "aa", squareSize, "w");\r
+ }\r
+ if(gameInfo.variant == VariantGothic) { // Vortex-like\r
+ pieceBitmap[0][WhiteMarshall] = DoLoadBitmap(hInst, "cv", squareSize, "s");\r
+ pieceBitmap[1][WhiteMarshall] = DoLoadBitmap(hInst, "cv", squareSize, "o");\r
+ pieceBitmap[2][WhiteMarshall] = DoLoadBitmap(hInst, "cv", squareSize, "w");\r
+ } else { // WinBoard standard\r
+ pieceBitmap[0][WhiteMarshall] = DoLoadBitmap(hInst, "c", squareSize, "s");\r
+ pieceBitmap[1][WhiteMarshall] = DoLoadBitmap(hInst, "c", squareSize, "o");\r
+ pieceBitmap[2][WhiteMarshall] = DoLoadBitmap(hInst, "c", squareSize, "w");\r
+ }\r
+ }\r
+\r
+\r
+ if(squareSize==72 || squareSize==49 || squareSize==33) { /* experiment with some home-made bitmaps */\r
+ pieceBitmap[0][WhiteFerz] = DoLoadBitmap(hInst, "f", squareSize, "s");\r
+ pieceBitmap[1][WhiteFerz] = DoLoadBitmap(hInst, "f", squareSize, "o");\r
+ pieceBitmap[2][WhiteFerz] = DoLoadBitmap(hInst, "f", squareSize, "w");\r
+ pieceBitmap[0][WhiteWazir] = DoLoadBitmap(hInst, "w", squareSize, "s");\r
+ pieceBitmap[1][WhiteWazir] = DoLoadBitmap(hInst, "w", squareSize, "o");\r
+ pieceBitmap[2][WhiteWazir] = DoLoadBitmap(hInst, "w", squareSize, "w");\r
+ pieceBitmap[0][WhiteAlfil] = DoLoadBitmap(hInst, "e", squareSize, "s");\r
+ pieceBitmap[1][WhiteAlfil] = DoLoadBitmap(hInst, "e", squareSize, "o");\r
+ pieceBitmap[2][WhiteAlfil] = DoLoadBitmap(hInst, "e", squareSize, "w");\r
+ pieceBitmap[0][WhiteMan] = DoLoadBitmap(hInst, "m", squareSize, "s");\r
+ pieceBitmap[1][WhiteMan] = DoLoadBitmap(hInst, "m", squareSize, "o");\r
+ pieceBitmap[2][WhiteMan] = DoLoadBitmap(hInst, "m", squareSize, "w");\r
+ pieceBitmap[0][WhiteCardinal] = DoLoadBitmap(hInst, "a", squareSize, "s");\r
+ pieceBitmap[1][WhiteCardinal] = DoLoadBitmap(hInst, "a", squareSize, "o");\r
+ pieceBitmap[2][WhiteCardinal] = DoLoadBitmap(hInst, "a", squareSize, "w");\r
+ pieceBitmap[0][WhiteDragon] = DoLoadBitmap(hInst, "dk", squareSize, "s");\r
+ pieceBitmap[1][WhiteDragon] = DoLoadBitmap(hInst, "dk", squareSize, "o");\r
+ pieceBitmap[2][WhiteDragon] = DoLoadBitmap(hInst, "dk", squareSize, "w");\r
+ pieceBitmap[0][WhiteFalcon] = DoLoadBitmap(hInst, "v", squareSize, "s");\r
+ pieceBitmap[1][WhiteFalcon] = DoLoadBitmap(hInst, "v", squareSize, "o");\r
+ pieceBitmap[2][WhiteFalcon] = DoLoadBitmap(hInst, "v", squareSize, "w");\r
+ pieceBitmap[0][WhiteCobra] = DoLoadBitmap(hInst, "s", squareSize, "s");\r
+ pieceBitmap[1][WhiteCobra] = DoLoadBitmap(hInst, "s", squareSize, "o");\r
+ pieceBitmap[2][WhiteCobra] = DoLoadBitmap(hInst, "s", squareSize, "w");\r
+ pieceBitmap[0][WhiteLance] = DoLoadBitmap(hInst, "l", squareSize, "s");\r
+ pieceBitmap[1][WhiteLance] = DoLoadBitmap(hInst, "l", squareSize, "o");\r
+ pieceBitmap[2][WhiteLance] = DoLoadBitmap(hInst, "l", squareSize, "w");\r
+ pieceBitmap[0][WhiteUnicorn] = DoLoadBitmap(hInst, "u", squareSize, "s");\r
+ pieceBitmap[1][WhiteUnicorn] = DoLoadBitmap(hInst, "u", squareSize, "o");\r
+ pieceBitmap[2][WhiteUnicorn] = DoLoadBitmap(hInst, "u", squareSize, "w");\r
+\r
+ if(gameInfo.variant == VariantShogi) { /* promoted Gold represemtations */\r
+ pieceBitmap[0][WhiteCannon] = DoLoadBitmap(hInst, "wp", squareSize, "s");\r
+ pieceBitmap[1][WhiteCannon] = DoLoadBitmap(hInst, "wp", squareSize, "o");\r
+ pieceBitmap[2][WhiteCannon] = DoLoadBitmap(hInst, "w", squareSize, "w");\r
+ pieceBitmap[0][WhiteNightrider] = DoLoadBitmap(hInst, "wn", squareSize, "s");\r
+ pieceBitmap[1][WhiteNightrider] = DoLoadBitmap(hInst, "wn", squareSize, "o");\r
+ pieceBitmap[2][WhiteNightrider] = DoLoadBitmap(hInst, "w", squareSize, "w");\r
+ pieceBitmap[0][WhiteSilver] = DoLoadBitmap(hInst, "ws", squareSize, "s");\r
+ pieceBitmap[1][WhiteSilver] = DoLoadBitmap(hInst, "ws", squareSize, "o");\r
+ pieceBitmap[2][WhiteSilver] = DoLoadBitmap(hInst, "w", squareSize, "w");\r
+ pieceBitmap[0][WhiteGrasshopper] = DoLoadBitmap(hInst, "wl", squareSize, "s");\r
+ pieceBitmap[1][WhiteGrasshopper] = DoLoadBitmap(hInst, "wl", squareSize, "o");\r
+ pieceBitmap[2][WhiteGrasshopper] = DoLoadBitmap(hInst, "w", squareSize, "w");\r
+ } else {\r
+ pieceBitmap[0][WhiteCannon] = DoLoadBitmap(hInst, "o", squareSize, "s");\r
+ pieceBitmap[1][WhiteCannon] = DoLoadBitmap(hInst, "o", squareSize, "o");\r
+ pieceBitmap[2][WhiteCannon] = DoLoadBitmap(hInst, "o", squareSize, "w");\r
+ pieceBitmap[0][WhiteNightrider] = DoLoadBitmap(hInst, "h", squareSize, "s");\r
+ pieceBitmap[1][WhiteNightrider] = DoLoadBitmap(hInst, "h", squareSize, "o");\r
+ pieceBitmap[2][WhiteNightrider] = DoLoadBitmap(hInst, "h", squareSize, "w");\r
+ pieceBitmap[0][WhiteSilver] = DoLoadBitmap(hInst, "cv", squareSize, "s");\r
+ pieceBitmap[1][WhiteSilver] = DoLoadBitmap(hInst, "cv", squareSize, "o");\r
+ pieceBitmap[2][WhiteSilver] = DoLoadBitmap(hInst, "cv", squareSize, "w");\r
+ pieceBitmap[0][WhiteGrasshopper] = DoLoadBitmap(hInst, "g", squareSize, "s");\r
+ pieceBitmap[1][WhiteGrasshopper] = DoLoadBitmap(hInst, "g", squareSize, "o");\r
+ pieceBitmap[2][WhiteGrasshopper] = DoLoadBitmap(hInst, "g", squareSize, "w");\r
+ }\r
+\r
+ } else { /* other size, no special bitmaps available. Use smaller symbols */\r
+ if((int)boardSize < 2) minorSize = sizeInfo[0].squareSize;\r
+ else minorSize = sizeInfo[(int)boardSize - 2].squareSize;\r
+ pieceBitmap[0][WhiteNightrider] = DoLoadBitmap(hInst, "n", minorSize, "s");\r
+ pieceBitmap[1][WhiteNightrider] = DoLoadBitmap(hInst, "n", minorSize, "o");\r
+ pieceBitmap[2][WhiteNightrider] = DoLoadBitmap(hInst, "n", minorSize, "w");\r
+ pieceBitmap[0][WhiteCardinal] = DoLoadBitmap(hInst, "b", minorSize, "s");\r
+ pieceBitmap[1][WhiteCardinal] = DoLoadBitmap(hInst, "b", minorSize, "o");\r
+ pieceBitmap[2][WhiteCardinal] = DoLoadBitmap(hInst, "b", minorSize, "w");\r
+ pieceBitmap[0][WhiteDragon] = DoLoadBitmap(hInst, "r", minorSize, "s");\r
+ pieceBitmap[1][WhiteDragon] = DoLoadBitmap(hInst, "r", minorSize, "o");\r
+ pieceBitmap[2][WhiteDragon] = DoLoadBitmap(hInst, "r", minorSize, "w");\r
+ pieceBitmap[0][WhiteGrasshopper] = DoLoadBitmap(hInst, "q", minorSize, "s");\r
+ pieceBitmap[1][WhiteGrasshopper] = DoLoadBitmap(hInst, "q", minorSize, "o");\r
+ pieceBitmap[2][WhiteGrasshopper] = DoLoadBitmap(hInst, "q", minorSize, "w");\r
+ }\r
+\r
+\r
+ if(gameInfo.variant == VariantShogi && squareSize == 58)\r
+ /* special Shogi support in this size */\r
+ { for (i=0; i<=2; i++) { /* replace all bitmaps */\r
+ for (piece = WhitePawn;\r
+ (int) piece < (int) BlackPawn;\r
+ piece = (ChessSquare) ((int) piece + 1)) {\r
+ if (pieceBitmap[i][piece] != NULL)\r
+ DeleteObject(pieceBitmap[i][piece]);\r
+ }\r
+ }\r
+ pieceBitmap[0][WhitePawn] = DoLoadBitmap(hInst, "sp", squareSize, "o");\r
+ pieceBitmap[0][WhiteKnight] = DoLoadBitmap(hInst, "sn", squareSize, "o");\r
+ pieceBitmap[0][WhiteBishop] = DoLoadBitmap(hInst, "sb", squareSize, "o");\r
+ pieceBitmap[0][WhiteRook] = DoLoadBitmap(hInst, "sr", squareSize, "o");\r
+ pieceBitmap[0][WhiteQueen] = DoLoadBitmap(hInst, "sl", squareSize, "o");\r
+ pieceBitmap[0][WhiteKing] = DoLoadBitmap(hInst, "sk", squareSize, "o");\r
+ pieceBitmap[0][WhiteFerz] = DoLoadBitmap(hInst, "sf", squareSize, "o");\r
+ pieceBitmap[0][WhiteWazir] = DoLoadBitmap(hInst, "sw", squareSize, "o");\r
+ pieceBitmap[0][WhiteCannon] = DoLoadBitmap(hInst, "su", squareSize, "o");\r
+ pieceBitmap[0][WhiteNightrider] = DoLoadBitmap(hInst, "sh", squareSize, "o");\r
+ pieceBitmap[0][WhiteCardinal] = DoLoadBitmap(hInst, "sa", squareSize, "o");\r
+ pieceBitmap[0][WhiteDragon] = DoLoadBitmap(hInst, "sc", squareSize, "o");\r
+ pieceBitmap[0][WhiteGrasshopper] = DoLoadBitmap(hInst, "sg", squareSize, "o");\r
+ pieceBitmap[0][WhiteSilver] = DoLoadBitmap(hInst, "ss", squareSize, "o");\r
+ pieceBitmap[1][WhitePawn] = DoLoadBitmap(hInst, "sp", squareSize, "o");\r
+ pieceBitmap[1][WhiteKnight] = DoLoadBitmap(hInst, "sn", squareSize, "o");\r
+ pieceBitmap[1][WhiteBishop] = DoLoadBitmap(hInst, "sb", squareSize, "o");\r
+ pieceBitmap[1][WhiteRook] = DoLoadBitmap(hInst, "sr", squareSize, "o");\r
+ pieceBitmap[1][WhiteQueen] = DoLoadBitmap(hInst, "sl", squareSize, "o");\r
+ pieceBitmap[1][WhiteKing] = DoLoadBitmap(hInst, "sk", squareSize, "o");\r
+ pieceBitmap[1][WhiteFerz] = DoLoadBitmap(hInst, "sf", squareSize, "o");\r
+ pieceBitmap[1][WhiteWazir] = DoLoadBitmap(hInst, "sw", squareSize, "o");\r
+ pieceBitmap[1][WhiteCannon] = DoLoadBitmap(hInst, "su", squareSize, "o");\r
+ pieceBitmap[1][WhiteNightrider] = DoLoadBitmap(hInst, "sh", squareSize, "o");\r
+ pieceBitmap[1][WhiteCardinal] = DoLoadBitmap(hInst, "sa", squareSize, "o");\r
+ pieceBitmap[1][WhiteDragon] = DoLoadBitmap(hInst, "sc", squareSize, "o");\r
+ pieceBitmap[1][WhiteGrasshopper] = DoLoadBitmap(hInst, "sg", squareSize, "o");\r
+ pieceBitmap[1][WhiteSilver] = DoLoadBitmap(hInst, "ss", squareSize, "o");\r
+ pieceBitmap[2][WhitePawn] = DoLoadBitmap(hInst, "sp", squareSize, "w");\r
+ pieceBitmap[2][WhiteKnight] = DoLoadBitmap(hInst, "sn", squareSize, "w");\r
+ pieceBitmap[2][WhiteBishop] = DoLoadBitmap(hInst, "sr", squareSize, "w");\r
+ pieceBitmap[2][WhiteRook] = DoLoadBitmap(hInst, "sr", squareSize, "w");\r
+ pieceBitmap[2][WhiteQueen] = DoLoadBitmap(hInst, "sl", squareSize, "w");\r
+ pieceBitmap[2][WhiteKing] = DoLoadBitmap(hInst, "sk", squareSize, "w");\r
+ pieceBitmap[2][WhiteFerz] = DoLoadBitmap(hInst, "sw", squareSize, "w");\r
+ pieceBitmap[2][WhiteWazir] = DoLoadBitmap(hInst, "sw", squareSize, "w");\r
+ pieceBitmap[2][WhiteCannon] = DoLoadBitmap(hInst, "sp", squareSize, "w");\r
+ pieceBitmap[2][WhiteNightrider] = DoLoadBitmap(hInst, "sn", squareSize, "w");\r
+ pieceBitmap[2][WhiteCardinal] = DoLoadBitmap(hInst, "sr", squareSize, "w");\r
+ pieceBitmap[2][WhiteDragon] = DoLoadBitmap(hInst, "sr", squareSize, "w");\r
+ pieceBitmap[2][WhiteGrasshopper] = DoLoadBitmap(hInst, "sl", squareSize, "w");\r
+ pieceBitmap[2][WhiteSilver] = DoLoadBitmap(hInst, "sw", squareSize, "w");\r
+ minorSize = 0;\r
+ }\r
}\r
\r
HBITMAP\r
SquareToPos(int row, int column, int * x, int * y)\r
{\r
if (flipView) {\r
- *x = boardRect.left + lineGap + ((BOARD_SIZE-1)-column) * (squareSize + lineGap);\r
+ *x = boardRect.left + lineGap + ((BOARD_WIDTH-1)-column) * (squareSize + lineGap);\r
*y = boardRect.top + lineGap + row * (squareSize + lineGap);\r
} else {\r
*x = boardRect.left + lineGap + column * (squareSize + lineGap);\r
- *y = boardRect.top + lineGap + ((BOARD_SIZE-1)-row) * (squareSize + lineGap);\r
+ *y = boardRect.top + lineGap + ((BOARD_HEIGHT-1)-row) * (squareSize + lineGap);\r
}\r
}\r
\r
VOID\r
DrawCoordsOnDC(HDC hdc)\r
{\r
- static char files[16] = {'1','2','3','4','5','6','7','8','8','7','6','5','4','3','2','1'};\r
- static char ranks[16] = {'h','g','f','e','d','c','b','a','a','b','c','d','e','f','g','h'};\r
+ static char files[24] = {'0', '1','2','3','4','5','6','7','8','9','0','1','1','0','9','8','7','6','5','4','3','2','1','0'};\r
+ static char ranks[24] = {'l', 'k','j','i','h','g','f','e','d','c','b','a','a','b','c','d','e','f','g','h','i','j','k','l'};\r
char str[2] = { NULLCHAR, NULLCHAR };\r
int oldMode, oldAlign, x, y, start, i;\r
HFONT oldFont;\r
if (!appData.showCoords)\r
return;\r
\r
- start = flipView ? 0 : 8;\r
+ start = flipView ? 1-(ONE!='1') : 23+(ONE!='1')-BOARD_HEIGHT;\r
\r
oldBrush = SelectObject(hdc, GetStockObject(BLACK_BRUSH));\r
oldMode = SetBkMode(hdc, (appData.monoMode ? OPAQUE : TRANSPARENT));\r
oldFont = SelectObject(hdc, font[boardSize][COORD_FONT]->hf);\r
\r
y = boardRect.top + lineGap;\r
- x = boardRect.left + lineGap;\r
+ x = boardRect.left + lineGap + gameInfo.holdingsWidth*(squareSize + lineGap);\r
\r
SetTextAlign(hdc, TA_LEFT|TA_TOP);\r
- for (i = 0; i < 8; i++) {\r
+ for (i = 0; i < BOARD_HEIGHT; i++) {\r
str[0] = files[start + i];\r
ExtTextOut(hdc, x + 2, y + 1, 0, NULL, str, 1, NULL);\r
y += squareSize + lineGap;\r
}\r
\r
+ start = flipView ? 12-(BOARD_RGHT-BOARD_LEFT) : 12;\r
+\r
SetTextAlign(hdc, TA_RIGHT|TA_BOTTOM);\r
- for (i = 0; i < 8; i++) {\r
+ for (i = 0; i < BOARD_RGHT - BOARD_LEFT; i++) {\r
str[0] = ranks[start + i];\r
ExtTextOut(hdc, x + squareSize - 2, y - 1, 0, NULL, str, 1, NULL);\r
x += squareSize + lineGap;\r
- } \r
+ }\r
\r
SelectObject(hdc, oldBrush);\r
SetBkMode(hdc, oldMode);\r
DrawGridOnDC(HDC hdc)\r
{\r
HPEN oldPen;\r
- \r
+\r
if (lineGap != 0) {\r
oldPen = SelectObject(hdc, gridPen);\r
- PolyPolyline(hdc, gridEndpoints, gridVertexCounts, BOARD_SIZE*2 + 2);\r
+ PolyPolyline(hdc, gridEndpoints, gridVertexCounts, BOARD_WIDTH+BOARD_HEIGHT + 2);\r
SelectObject(hdc, oldPen);\r
}\r
}\r
if (lineGap == 0) return;\r
if (flipView) {\r
x1 = boardRect.left +\r
- lineGap/2 + ((BOARD_SIZE-1)-x) * (squareSize + lineGap);\r
+ lineGap/2 + ((BOARD_WIDTH-1)-x) * (squareSize + lineGap);\r
y1 = boardRect.top +\r
lineGap/2 + y * (squareSize + lineGap);\r
} else {\r
x1 = boardRect.left +\r
lineGap/2 + x * (squareSize + lineGap);\r
y1 = boardRect.top +\r
- lineGap/2 + ((BOARD_SIZE-1)-y) * (squareSize + lineGap);\r
+ lineGap/2 + ((BOARD_HEIGHT-1)-y) * (squareSize + lineGap);\r
}\r
hPen = pen ? premovePen : highlightPen;\r
oldPen = SelectObject(hdc, on ? hPen : gridPen);\r
{\r
int i;\r
for (i=0; i<2; i++) {\r
- if (highlightInfo.sq[i].x >= 0 && highlightInfo.sq[i].y >= 0) \r
+ if (highlightInfo.sq[i].x >= 0 && highlightInfo.sq[i].y >= 0)\r
DrawHighlightOnDC(hdc, TRUE,\r
- highlightInfo.sq[i].x, highlightInfo.sq[i].y,\r
- HIGHLIGHT_PEN);\r
+ highlightInfo.sq[i].x, highlightInfo.sq[i].y,\r
+ HIGHLIGHT_PEN);\r
}\r
for (i=0; i<2; i++) {\r
- if (premoveHighlightInfo.sq[i].x >= 0 && \r
- premoveHighlightInfo.sq[i].y >= 0) {\r
- DrawHighlightOnDC(hdc, TRUE,\r
- premoveHighlightInfo.sq[i].x, \r
- premoveHighlightInfo.sq[i].y,\r
- PREMOVE_PEN);\r
+ if (premoveHighlightInfo.sq[i].x >= 0 &&\r
+ premoveHighlightInfo.sq[i].y >= 0) {\r
+ DrawHighlightOnDC(hdc, TRUE,\r
+ premoveHighlightInfo.sq[i].x,\r
+ premoveHighlightInfo.sq[i].y,\r
+ PREMOVE_PEN);\r
}\r
}\r
}\r
{\r
HBITMAP oldBitmap;\r
HBRUSH oldBrush;\r
+ int tmpSize;\r
\r
if (appData.blindfold) return;\r
\r
+ /* [AS] Use font-based pieces if needed */\r
+ if( fontBitmapSquareSize >= 0 && squareSize > 32 ) {\r
+ /* Create piece bitmaps, or do nothing if piece set is up to date */\r
+ CreatePiecesFromFont();\r
+\r
+ if( fontBitmapSquareSize == squareSize ) {\r
+ int index = TranslatePieceToFontPiece(piece);\r
+\r
+ SelectObject( tmphdc, hPieceMask[ index ] );\r
+\r
+ BitBlt( hdc,\r
+ x, y,\r
+ squareSize, squareSize,\r
+ tmphdc,\r
+ 0, 0,\r
+ SRCAND );\r
+\r
+ SelectObject( tmphdc, hPieceFace[ index ] );\r
+\r
+ BitBlt( hdc,\r
+ x, y,\r
+ squareSize, squareSize,\r
+ tmphdc,\r
+ 0, 0,\r
+ SRCPAINT );\r
+\r
+ return;\r
+ }\r
+ }\r
+\r
if (appData.monoMode) {\r
- SelectObject(tmphdc, PieceBitmap(piece, \r
+ SelectObject(tmphdc, PieceBitmap(piece,\r
color == sqcolor ? OUTLINE_PIECE : SOLID_PIECE));\r
BitBlt(hdc, x, y, squareSize, squareSize, tmphdc, 0, 0,\r
- sqcolor ? SRCCOPY : NOTSRCCOPY);\r
+ sqcolor ? SRCCOPY : NOTSRCCOPY);\r
} else {\r
- if (color) {\r
+ tmpSize = squareSize;\r
+ if(minorSize &&\r
+ ((piece >= (int)WhiteNightrider && piece <= WhiteGrasshopper) ||\r
+ (piece >= (int)BlackNightrider && piece <= BlackGrasshopper)) ) {\r
+ /* [HGM] no bitmap available for promoted pieces in Crazyhouse */\r
+ /* Bitmaps of smaller size are substituted, but we have to align them */\r
+ x += (squareSize - minorSize)>>1;\r
+ y += squareSize - minorSize - 2;\r
+ tmpSize = minorSize;\r
+ }\r
+ if (color || appData.allWhite ) {\r
oldBitmap = SelectObject(tmphdc, PieceBitmap(piece, WHITE_PIECE));\r
- oldBrush = SelectObject(hdc, whitePieceBrush);\r
- BitBlt(hdc, x, y, squareSize, squareSize, tmphdc, 0, 0, 0x00B8074A);\r
+ if( color )\r
+ oldBrush = SelectObject(hdc, whitePieceBrush);\r
+ else oldBrush = SelectObject(hdc, blackPieceBrush);\r
+ if(appData.upsideDown && color==flipView)\r
+ StretchBlt(hdc, x+tmpSize, y+tmpSize, -tmpSize, -tmpSize, tmphdc, 0, 0, tmpSize, tmpSize, 0x00B8074A);\r
+ else\r
+ BitBlt(hdc, x, y, tmpSize, tmpSize, tmphdc, 0, 0, 0x00B8074A);\r
#if 0\r
/* Use black piece color for outline of white pieces */\r
/* Not sure this looks really good (though xboard does it).\r
- Maybe better to have another selectable color, default black */\r
+ Maybe better to have another selectable color, default black */\r
SelectObject(hdc, blackPieceBrush); /* could have own brush */\r
SelectObject(tmphdc, PieceBitmap(piece, OUTLINE_PIECE));\r
- BitBlt(hdc, x, y, squareSize, squareSize, tmphdc, 0, 0, 0x00B8074A);\r
+ BitBlt(hdc, x, y, tmpSize, tmpSize, tmphdc, 0, 0, 0x00B8074A);\r
#else\r
/* Use black for outline of white pieces */\r
SelectObject(tmphdc, PieceBitmap(piece, OUTLINE_PIECE));\r
- BitBlt(hdc, x, y, squareSize, squareSize, tmphdc, 0, 0, SRCAND);\r
+ if(appData.upsideDown && color==flipView)\r
+ StretchBlt(hdc, x+tmpSize, y+tmpSize, -tmpSize, -tmpSize, tmphdc, 0, 0, tmpSize, tmpSize, SRCAND);\r
+ else\r
+ BitBlt(hdc, x, y, tmpSize, tmpSize, tmphdc, 0, 0, SRCAND);\r
#endif\r
} else {\r
#if 0\r
/* Use white piece color for details of black pieces */\r
/* Requires filled-in solid bitmaps (BLACK_PIECE class); the\r
- WHITE_PIECE ones aren't always the right shape. */\r
+ WHITE_PIECE ones aren't always the right shape. */\r
/* Not sure this looks really good (though xboard does it).\r
- Maybe better to have another selectable color, default medium gray? */\r
+ Maybe better to have another selectable color, default medium gray? */\r
oldBitmap = SelectObject(tmphdc, PieceBitmap(piece, BLACK_PIECE));\r
oldBrush = SelectObject(hdc, whitePieceBrush); /* could have own brush */\r
- BitBlt(hdc, x, y, squareSize, squareSize, tmphdc, 0, 0, 0x00B8074A);\r
+ BitBlt(hdc, x, y, tmpSize, tmpSize, tmphdc, 0, 0, 0x00B8074A);\r
SelectObject(tmphdc, PieceBitmap(piece, SOLID_PIECE));\r
SelectObject(hdc, blackPieceBrush);\r
- BitBlt(hdc, x, y, squareSize, squareSize, tmphdc, 0, 0, 0x00B8074A);\r
+ BitBlt(hdc, x, y, tmpSize, tmpSize, tmphdc, 0, 0, 0x00B8074A);\r
#else\r
/* Use square color for details of black pieces */\r
oldBitmap = SelectObject(tmphdc, PieceBitmap(piece, SOLID_PIECE));\r
oldBrush = SelectObject(hdc, blackPieceBrush);\r
- BitBlt(hdc, x, y, squareSize, squareSize, tmphdc, 0, 0, 0x00B8074A);\r
+ if(appData.upsideDown && !flipView)\r
+ StretchBlt(hdc, x+tmpSize, y+tmpSize, -tmpSize, -tmpSize, tmphdc, 0, 0, tmpSize, tmpSize, 0x00B8074A);\r
+ else\r
+ BitBlt(hdc, x, y, tmpSize, tmpSize, tmphdc, 0, 0, 0x00B8074A);\r
#endif\r
}\r
SelectObject(hdc, oldBrush);\r
}\r
}\r
\r
+/* [AS] Compute a drawing mode for a square, based on specified settings (see DrawTile) */\r
+int GetBackTextureMode( int algo )\r
+{\r
+ int result = BACK_TEXTURE_MODE_DISABLED;\r
+\r
+ switch( algo )\r
+ {\r
+ case BACK_TEXTURE_MODE_PLAIN:\r
+ result = 1; /* Always use identity map */\r
+ break;\r
+ case BACK_TEXTURE_MODE_FULL_RANDOM:\r
+ result = 1 + (myrandom() % 3); /* Pick a transformation at random */\r
+ break;\r
+ }\r
+\r
+ return result;\r
+}\r
+\r
+/*\r
+ [AS] Compute and save texture drawing info, otherwise we may not be able\r
+ to handle redraws cleanly (as random numbers would always be different).\r
+*/\r
+VOID RebuildTextureSquareInfo()\r
+{\r
+ BITMAP bi;\r
+ int lite_w = 0;\r
+ int lite_h = 0;\r
+ int dark_w = 0;\r
+ int dark_h = 0;\r
+ int row;\r
+ int col;\r
+\r
+ ZeroMemory( &backTextureSquareInfo, sizeof(backTextureSquareInfo) );\r
+\r
+ if( liteBackTexture != NULL ) {\r
+ if( GetObject( liteBackTexture, sizeof(bi), &bi ) > 0 ) {\r
+ lite_w = bi.bmWidth;\r
+ lite_h = bi.bmHeight;\r
+ }\r
+ }\r
+\r
+ if( darkBackTexture != NULL ) {\r
+ if( GetObject( darkBackTexture, sizeof(bi), &bi ) > 0 ) {\r
+ dark_w = bi.bmWidth;\r
+ dark_h = bi.bmHeight;\r
+ }\r
+ }\r
+\r
+ for( row=0; row<BOARD_HEIGHT; row++ ) {\r
+ for( col=0; col<BOARD_WIDTH; col++ ) {\r
+ if( (col + row) & 1 ) {\r
+ /* Lite square */\r
+ if( lite_w >= squareSize && lite_h >= squareSize ) {\r
+ backTextureSquareInfo[row][col].x = col * (lite_w - squareSize) / (BOARD_WIDTH-1); /* [HGM] divide by size-1 in stead of size! */\r
+ backTextureSquareInfo[row][col].y = (BOARD_HEIGHT-1-row) * (lite_h - squareSize) / (BOARD_HEIGHT-1);\r
+ backTextureSquareInfo[row][col].mode = GetBackTextureMode(liteBackTextureMode);\r
+ }\r
+ }\r
+ else {\r
+ /* Dark square */\r
+ if( dark_w >= squareSize && dark_h >= squareSize ) {\r
+ backTextureSquareInfo[row][col].x = col * (dark_w - squareSize) / (BOARD_WIDTH-1);\r
+ backTextureSquareInfo[row][col].y = (BOARD_HEIGHT-1-row) * (dark_h - squareSize) / (BOARD_HEIGHT-1);\r
+ backTextureSquareInfo[row][col].mode = GetBackTextureMode(darkBackTextureMode);\r
+ }\r
+ }\r
+ }\r
+ }\r
+}\r
+\r
+/* [AS] Arrow highlighting support */\r
+\r
+static int A_WIDTH = 5; /* Width of arrow body */\r
+\r
+#define A_HEIGHT_FACTOR 6 /* Length of arrow "point", relative to body width */\r
+#define A_WIDTH_FACTOR 3 /* Width of arrow "point", relative to body width */\r
+\r
+static double Sqr( double x )\r
+{\r
+ return x*x;\r
+}\r
+\r
+static int Round( double x )\r
+{\r
+ return (int) (x + 0.5);\r
+}\r
+\r
+/* Draw an arrow between two points using current settings */\r
+VOID DrawArrowBetweenPoints( HDC hdc, int s_x, int s_y, int d_x, int d_y )\r
+{\r
+ POINT arrow[7];\r
+ double dx, dy, j, k, x, y;\r
+\r
+ if( d_x == s_x ) {\r
+ int h = (d_y > s_y) ? +A_WIDTH*A_HEIGHT_FACTOR : -A_WIDTH*A_HEIGHT_FACTOR;\r
+\r
+ arrow[0].x = s_x + A_WIDTH;\r
+ arrow[0].y = s_y;\r
+\r
+ arrow[1].x = s_x + A_WIDTH;\r
+ arrow[1].y = d_y - h;\r
+\r
+ arrow[2].x = s_x + A_WIDTH*A_WIDTH_FACTOR;\r
+ arrow[2].y = d_y - h;\r
+\r
+ arrow[3].x = d_x;\r
+ arrow[3].y = d_y;\r
+\r
+ arrow[4].x = s_x - A_WIDTH*A_WIDTH_FACTOR;\r
+ arrow[4].y = d_y - h;\r
+\r
+ arrow[5].x = s_x - A_WIDTH;\r
+ arrow[5].y = d_y - h;\r
+\r
+ arrow[6].x = s_x - A_WIDTH;\r
+ arrow[6].y = s_y;\r
+ }\r
+ else if( d_y == s_y ) {\r
+ int w = (d_x > s_x) ? +A_WIDTH*A_HEIGHT_FACTOR : -A_WIDTH*A_HEIGHT_FACTOR;\r
+\r
+ arrow[0].x = s_x;\r
+ arrow[0].y = s_y + A_WIDTH;\r
+\r
+ arrow[1].x = d_x - w;\r
+ arrow[1].y = s_y + A_WIDTH;\r
+\r
+ arrow[2].x = d_x - w;\r
+ arrow[2].y = s_y + A_WIDTH*A_WIDTH_FACTOR;\r
+\r
+ arrow[3].x = d_x;\r
+ arrow[3].y = d_y;\r
+\r
+ arrow[4].x = d_x - w;\r
+ arrow[4].y = s_y - A_WIDTH*A_WIDTH_FACTOR;\r
+\r
+ arrow[5].x = d_x - w;\r
+ arrow[5].y = s_y - A_WIDTH;\r
+\r
+ arrow[6].x = s_x;\r
+ arrow[6].y = s_y - A_WIDTH;\r
+ }\r
+ else {\r
+ /* [AS] Needed a lot of paper for this! :-) */\r
+ dy = (double) (d_y - s_y) / (double) (d_x - s_x);\r
+ dx = (double) (s_x - d_x) / (double) (s_y - d_y);\r
+\r
+ j = sqrt( Sqr(A_WIDTH) / (1.0 + Sqr(dx)) );\r
+\r
+ k = sqrt( Sqr(A_WIDTH*A_HEIGHT_FACTOR) / (1.0 + Sqr(dy)) );\r
+\r
+ x = s_x;\r
+ y = s_y;\r
+\r
+ arrow[0].x = Round(x - j);\r
+ arrow[0].y = Round(y + j*dx);\r
+\r
+ arrow[1].x = Round(x + j);\r
+ arrow[1].y = Round(y - j*dx);\r
+\r
+ if( d_x > s_x ) {\r
+ x = (double) d_x - k;\r
+ y = (double) d_y - k*dy;\r
+ }\r
+ else {\r
+ x = (double) d_x + k;\r
+ y = (double) d_y + k*dy;\r
+ }\r
+\r
+ arrow[2].x = Round(x + j);\r
+ arrow[2].y = Round(y - j*dx);\r
+\r
+ arrow[3].x = Round(x + j*A_WIDTH_FACTOR);\r
+ arrow[3].y = Round(y - j*A_WIDTH_FACTOR*dx);\r
+\r
+ arrow[4].x = d_x;\r
+ arrow[4].y = d_y;\r
+\r
+ arrow[5].x = Round(x - j*A_WIDTH_FACTOR);\r
+ arrow[5].y = Round(y + j*A_WIDTH_FACTOR*dx);\r
+\r
+ arrow[6].x = Round(x - j);\r
+ arrow[6].y = Round(y + j*dx);\r
+ }\r
+\r
+ Polygon( hdc, arrow, 7 );\r
+}\r
+\r
+/* [AS] Draw an arrow between two squares */\r
+VOID DrawArrowBetweenSquares( HDC hdc, int s_col, int s_row, int d_col, int d_row )\r
+{\r
+ int s_x, s_y, d_x, d_y;\r
+ HPEN hpen;\r
+ HPEN holdpen;\r
+ HBRUSH hbrush;\r
+ HBRUSH holdbrush;\r
+ LOGBRUSH stLB;\r
+\r
+ if( s_col == d_col && s_row == d_row ) {\r
+ return;\r
+ }\r
+\r
+ /* Get source and destination points */\r
+ SquareToPos( s_row, s_col, &s_x, &s_y);\r
+ SquareToPos( d_row, d_col, &d_x, &d_y);\r
+\r
+ if( d_y > s_y ) {\r
+ d_y += squareSize / 4;\r
+ }\r
+ else if( d_y < s_y ) {\r
+ d_y += 3 * squareSize / 4;\r
+ }\r
+ else {\r
+ d_y += squareSize / 2;\r
+ }\r
+\r
+ if( d_x > s_x ) {\r
+ d_x += squareSize / 4;\r
+ }\r
+ else if( d_x < s_x ) {\r
+ d_x += 3 * squareSize / 4;\r
+ }\r
+ else {\r
+ d_x += squareSize / 2;\r
+ }\r
+\r
+ s_x += squareSize / 2;\r
+ s_y += squareSize / 2;\r
+\r
+ /* Adjust width */\r
+ A_WIDTH = squareSize / 14;\r
+\r
+ /* Draw */\r
+ stLB.lbStyle = BS_SOLID;\r
+ stLB.lbColor = appData.highlightArrowColor;\r
+ stLB.lbHatch = 0;\r
+\r
+ hpen = CreatePen( PS_SOLID, 2, RGB(0x00,0x00,0x00) );\r
+ holdpen = SelectObject( hdc, hpen );\r
+ hbrush = CreateBrushIndirect( &stLB );\r
+ holdbrush = SelectObject( hdc, hbrush );\r
+\r
+ DrawArrowBetweenPoints( hdc, s_x, s_y, d_x, d_y );\r
+\r
+ SelectObject( hdc, holdpen );\r
+ SelectObject( hdc, holdbrush );\r
+ DeleteObject( hpen );\r
+ DeleteObject( hbrush );\r
+}\r
+\r
+BOOL HasHighlightInfo()\r
+{\r
+ BOOL result = FALSE;\r
+\r
+ if( highlightInfo.sq[0].x >= 0 && highlightInfo.sq[0].y >= 0 &&\r
+ highlightInfo.sq[1].x >= 0 && highlightInfo.sq[1].y >= 0 )\r
+ {\r
+ result = TRUE;\r
+ }\r
+\r
+ return result;\r
+}\r
+\r
+BOOL IsDrawArrowEnabled()\r
+{\r
+ BOOL result = FALSE;\r
+\r
+ if( appData.highlightMoveWithArrow && squareSize >= 32 ) {\r
+ result = TRUE;\r
+ }\r
+\r
+ return result;\r
+}\r
+\r
+VOID DrawArrowHighlight( HDC hdc )\r
+{\r
+ if( IsDrawArrowEnabled() && HasHighlightInfo() ) {\r
+ DrawArrowBetweenSquares( hdc,\r
+ highlightInfo.sq[0].x, highlightInfo.sq[0].y,\r
+ highlightInfo.sq[1].x, highlightInfo.sq[1].y );\r
+ }\r
+}\r
+\r
+HRGN GetArrowHighlightClipRegion( HDC hdc )\r
+{\r
+ HRGN result = NULL;\r
+\r
+ if( HasHighlightInfo() ) {\r
+ int x1, y1, x2, y2;\r
+ int sx, sy, dx, dy;\r
+\r
+ SquareToPos(highlightInfo.sq[0].y, highlightInfo.sq[0].x, &x1, &y1 );\r
+ SquareToPos(highlightInfo.sq[1].y, highlightInfo.sq[1].x, &x2, &y2 );\r
+\r
+ sx = MIN( x1, x2 );\r
+ sy = MIN( y1, y2 );\r
+ dx = MAX( x1, x2 ) + squareSize;\r
+ dy = MAX( y1, y2 ) + squareSize;\r
+\r
+ result = CreateRectRgn( sx, sy, dx, dy );\r
+ }\r
+\r
+ return result;\r
+}\r
+\r
+/*\r
+ Warning: this function modifies the behavior of several other functions.\r
+\r
+ Basically, Winboard is optimized to avoid drawing the whole board if not strictly\r
+ needed. Unfortunately, the decision whether or not to perform a full or partial\r
+ repaint is scattered all over the place, which is not good for features such as\r
+ "arrow highlighting" that require a full repaint of the board.\r
+\r
+ So, I've tried to patch the code where I thought it made sense (e.g. after or during\r
+ user interaction, when speed is not so important) but especially to avoid errors\r
+ in the displayed graphics.\r
+\r
+ In such patched places, I always try refer to this function so there is a single\r
+ place to maintain knowledge.\r
+\r
+ To restore the original behavior, just return FALSE unconditionally.\r
+*/\r
+BOOL IsFullRepaintPreferrable()\r
+{\r
+ BOOL result = FALSE;\r
+\r
+ if( (appData.highlightLastMove || appData.highlightDragging) && IsDrawArrowEnabled() ) {\r
+ /* Arrow may appear on the board */\r
+ result = TRUE;\r
+ }\r
+\r
+ return result;\r
+}\r
+\r
+/*\r
+ This function is called by DrawPosition to know whether a full repaint must\r
+ be forced or not.\r
+\r
+ Only DrawPosition may directly call this function, which makes use of\r
+ some state information. Other function should call DrawPosition specifying\r
+ the repaint flag, and can use IsFullRepaintPreferrable if needed.\r
+*/\r
+BOOL DrawPositionNeedsFullRepaint()\r
+{\r
+ BOOL result = FALSE;\r
+\r
+ /*\r
+ Probably a slightly better policy would be to trigger a full repaint\r
+ when animInfo.piece changes state (i.e. empty -> non-empty and viceversa),\r
+ but animation is fast enough that it's difficult to notice.\r
+ */\r
+ if( animInfo.piece == EmptySquare ) {\r
+ if( (appData.highlightLastMove || appData.highlightDragging) && IsDrawArrowEnabled() && HasHighlightInfo() ) {\r
+ result = TRUE;\r
+ }\r
+ }\r
+\r
+ return result;\r
+}\r
+\r
VOID\r
DrawBoardOnDC(HDC hdc, Board board, HDC tmphdc)\r
{\r
int row, column, x, y, square_color, piece_color;\r
ChessSquare piece;\r
HBRUSH oldBrush;\r
+ HDC texture_hdc = NULL;\r
+\r
+ /* [AS] Initialize background textures if needed */\r
+ if( liteBackTexture != NULL || darkBackTexture != NULL ) {\r
+ static int backTextureBoardSize; /* [HGM] boardsize: also new texture if board format changed */\r
+ if( backTextureSquareSize != squareSize\r
+ || backTextureBoardSize != BOARD_WIDTH+BOARD_SIZE*BOARD_HEIGHT) {\r
+ backTextureBoardSize = BOARD_WIDTH+BOARD_SIZE*BOARD_HEIGHT;\r
+ backTextureSquareSize = squareSize;\r
+ RebuildTextureSquareInfo();\r
+ }\r
+\r
+ texture_hdc = CreateCompatibleDC( hdc );\r
+ }\r
+\r
+ for (row = 0; row < BOARD_HEIGHT; row++) {\r
+ for (column = 0; column < BOARD_WIDTH; column++) {\r
\r
- for (row = 0; row < BOARD_SIZE; row++) {\r
- for (column = 0; column < BOARD_SIZE; column++) {\r
- \r
SquareToPos(row, column, &x, &y);\r
\r
piece = board[row][column];\r
\r
square_color = ((column + row) % 2) == 1;\r
+ if( gameInfo.variant == VariantXiangqi ) {\r
+ square_color = !InPalace(row, column);\r
+ if(BOARD_HEIGHT&1) { if(row==BOARD_HEIGHT/2) square_color ^= 1; }\r
+ else if(row < BOARD_HEIGHT/2) square_color ^= 1;\r
+ }\r
piece_color = (int) piece < (int) BlackPawn;\r
\r
+\r
+ /* [HGM] holdings file: light square or black */\r
+ if(column == BOARD_LEFT-2) {\r
+ if( row > BOARD_HEIGHT - gameInfo.holdingsSize - 1 )\r
+ square_color = 1;\r
+ else {\r
+ DisplayHoldingsCount(hdc, x, y, 0, 0); /* black out */\r
+ continue;\r
+ }\r
+ } else\r
+ if(column == BOARD_RGHT + 1 ) {\r
+ if( row < gameInfo.holdingsSize )\r
+ square_color = 1;\r
+ else {\r
+ DisplayHoldingsCount(hdc, x, y, 0, 0);\r
+ continue;\r
+ }\r
+ }\r
+ if(column == BOARD_LEFT-1 ) /* left align */\r
+ DisplayHoldingsCount(hdc, x, y, flipView, (int) board[row][column]);\r
+ else if( column == BOARD_RGHT) /* right align */\r
+ DisplayHoldingsCount(hdc, x, y, !flipView, (int) board[row][column]);\r
+ else\r
if (appData.monoMode) {\r
if (piece == EmptySquare) {\r
BitBlt(hdc, x, y, squareSize, squareSize, 0, 0, 0,\r
- square_color ? WHITENESS : BLACKNESS);\r
+ square_color ? WHITENESS : BLACKNESS);\r
} else {\r
DrawPieceOnDC(hdc, piece, piece_color, square_color, x, y, tmphdc);\r
}\r
- } else {\r
- oldBrush = SelectObject(hdc, square_color ?\r
- lightSquareBrush : darkSquareBrush);\r
+ }\r
+ else if( backTextureSquareInfo[row][column].mode > 0 ) {\r
+ /* [AS] Draw the square using a texture bitmap */\r
+ HBITMAP hbm = SelectObject( texture_hdc, square_color ? liteBackTexture : darkBackTexture );\r
+ int r = row, c = column; // [HGM] do not flip board in flipView\r
+ if(flipView) { r = BOARD_HEIGHT-1 - r; c = BOARD_WIDTH-1 - c; }\r
+\r
+ DrawTile( x, y,\r
+ squareSize, squareSize,\r
+ hdc,\r
+ texture_hdc,\r
+ backTextureSquareInfo[r][c].mode,\r
+ backTextureSquareInfo[r][c].x,\r
+ backTextureSquareInfo[r][c].y );\r
+\r
+ SelectObject( texture_hdc, hbm );\r
+\r
+ if (piece != EmptySquare) {\r
+ DrawPieceOnDC(hdc, piece, piece_color, -1, x, y, tmphdc);\r
+ }\r
+ }\r
+ else {\r
+ HBRUSH brush = square_color ? lightSquareBrush : darkSquareBrush;\r
+\r
+ oldBrush = SelectObject(hdc, brush );\r
BitBlt(hdc, x, y, squareSize, squareSize, 0, 0, 0, PATCOPY);\r
SelectObject(hdc, oldBrush);\r
if (piece != EmptySquare)\r
}\r
}\r
}\r
+\r
+ if( texture_hdc != NULL ) {\r
+ DeleteDC( texture_hdc );\r
+ }\r
+}\r
+\r
+int saveDiagFlag = 0; FILE *diagFile; // [HGM] diag\r
+void fputDW(FILE *f, int x)\r
+{\r
+ fputc(x & 255, f);\r
+ fputc(x>>8 & 255, f);\r
+ fputc(x>>16 & 255, f);\r
+ fputc(x>>24 & 255, f);\r
}\r
\r
#define MAX_CLIPS 200 /* more than enough */\r
\r
VOID\r
+DrawLogoOnDC(HDC hdc, RECT logoRect, HBITMAP logo)\r
+{\r
+// HBITMAP bufferBitmap;\r
+ BITMAP bi;\r
+// RECT Rect;\r
+ HDC tmphdc;\r
+ HBITMAP hbm;\r
+ int w = 100, h = 50;\r
+\r
+ if(logo == NULL) return;\r
+// GetClientRect(hwndMain, &Rect);\r
+// bufferBitmap = CreateCompatibleBitmap(hdc, Rect.right-Rect.left+1,\r
+// Rect.bottom-Rect.top+1);\r
+ tmphdc = CreateCompatibleDC(hdc);\r
+ hbm = SelectObject(tmphdc, logo);\r
+ if( GetObject( logo, sizeof(bi), &bi ) > 0 ) {\r
+ w = bi.bmWidth;\r
+ h = bi.bmHeight;\r
+ }\r
+ StretchBlt(hdc, logoRect.left, logoRect.top, logoRect.right - logoRect.left,\r
+ logoRect.bottom - logoRect.top, tmphdc, 0, 0, w, h, SRCCOPY);\r
+ SelectObject(tmphdc, hbm);\r
+ DeleteDC(tmphdc);\r
+}\r
+\r
+VOID\r
HDCDrawPosition(HDC hdc, BOOLEAN repaint, Board board)\r
{\r
static Board lastReq, lastDrawn;\r
* caller tell it that. I think this can safely be set to FALSE - but\r
* if we trust the callers not to request full repaints unnessesarily, then\r
* we could skip some clipping work. In other words, only request a full\r
- * redraw when the majority of pieces have changed positions (ie. flip, \r
+ * redraw when the majority of pieces have changed positions (ie. flip,\r
* gamestart and similar) --Hawk\r
*/\r
Boolean fullrepaint = repaint;\r
\r
+ if( DrawPositionNeedsFullRepaint() ) {\r
+ fullrepaint = TRUE;\r
+ }\r
+\r
+#if 0\r
+ if( fullrepaint ) {\r
+ static int repaint_count = 0;\r
+ char buf[128];\r
+\r
+ repaint_count++;\r
+ sprintf( buf, "FULL repaint: %d\n", repaint_count );\r
+ OutputDebugString( buf );\r
+ }\r
+#endif\r
+\r
if (board == NULL) {\r
if (!lastReqValid) {\r
return;\r
"dragInfo.from (%d,%d)\n"\r
"dragInfo.start (%d,%d)\n"\r
"dragInfo.pos (%d,%d)\n"\r
- "dragInfo.lastpos (%d,%d)\n", \r
+ "dragInfo.lastpos (%d,%d)\n",\r
repaint ? "TRUE" : "FALSE",\r
- dragInfo.from.x, dragInfo.from.y, \r
+ dragInfo.from.x, dragInfo.from.y,\r
dragInfo.start.x, dragInfo.start.y,\r
dragInfo.pos.x, dragInfo.pos.y,\r
dragInfo.lastpos.x, dragInfo.lastpos.y);\r
fprintf(debugFP, "prev: ");\r
- for (row = 0; row < 8; row++) {\r
- for (column = 0; column < 8; column++) {\r
+ for (row = 0; row < BOARD_HEIGHT; row++) {\r
+ for (column = 0; column < BOARD_WIDTH; column++) {\r
fprintf(debugFP, "%d ", lastDrawn[row][column]);\r
}\r
}\r
fprintf(debugFP, "\n");\r
fprintf(debugFP, "board: ");\r
- for (row = 0; row < 8; row++) {\r
- for (column = 0; column < 8; column++) {\r
+ for (row = 0; row < BOARD_HEIGHT; row++) {\r
+ for (column = 0; column < BOARD_WIDTH; column++) {\r
fprintf(debugFP, "%d ", board[row][column]);\r
}\r
}\r
hdcmem = CreateCompatibleDC(hdc);\r
tmphdc = CreateCompatibleDC(hdc);\r
\r
- /* Figure out which squares need updating by comparing the \r
+ /* If dragging is in progress, we temporarely remove the piece */\r
+ /* [HGM] or temporarily decrease count if stacked */\r
+ /* !! Moved to before board compare !! */\r
+ if (dragInfo.from.x >= 0 && dragInfo.pos.x >= 0) {\r
+ dragged_piece = board[dragInfo.from.y][dragInfo.from.x];\r
+ if(dragInfo.from.x == BOARD_LEFT-2 ) {\r
+ if(--board[dragInfo.from.y][dragInfo.from.x+1] == 0 )\r
+ board[dragInfo.from.y][dragInfo.from.x] = EmptySquare;\r
+ } else\r
+ if(dragInfo.from.x == BOARD_RGHT+1) {\r
+ if(--board[dragInfo.from.y][dragInfo.from.x-1] == 0 )\r
+ board[dragInfo.from.y][dragInfo.from.x] = EmptySquare;\r
+ } else\r
+ board[dragInfo.from.y][dragInfo.from.x] = EmptySquare;\r
+ }\r
+\r
+ /* Figure out which squares need updating by comparing the\r
* newest board with the last drawn board and checking if\r
* flipping has changed.\r
*/\r
if (!fullrepaint && lastDrawnValid && lastDrawnFlipView == flipView) {\r
- for (row = 0; row < 8; row++) {\r
- for (column = 0; column < 8; column++) {\r
- if (lastDrawn[row][column] != board[row][column]) {\r
- SquareToPos(row, column, &x, &y);\r
- clips[num_clips++] =\r
- CreateRectRgn(x, y, x + squareSize, y + squareSize);\r
- }\r
+ for (row = 0; row < BOARD_HEIGHT; row++) { /* [HGM] true size, not 8 */\r
+ for (column = 0; column < BOARD_WIDTH; column++) {\r
+ if (lastDrawn[row][column] != board[row][column]) {\r
+ SquareToPos(row, column, &x, &y);\r
+ clips[num_clips++] =\r
+ CreateRectRgn(x, y, x + squareSize, y + squareSize);\r
+ }\r
}\r
}\r
for (i=0; i<2; i++) {\r
if (lastDrawnHighlight.sq[i].x != highlightInfo.sq[i].x ||\r
- lastDrawnHighlight.sq[i].y != highlightInfo.sq[i].y) {\r
- if (lastDrawnHighlight.sq[i].x >= 0 &&\r
- lastDrawnHighlight.sq[i].y >= 0) {\r
- SquareToPos(lastDrawnHighlight.sq[i].y,\r
- lastDrawnHighlight.sq[i].x, &x, &y);\r
- clips[num_clips++] =\r
- CreateRectRgn(x - lineGap, y - lineGap, \r
- x + squareSize + lineGap, y + squareSize + lineGap);\r
- }\r
- if (highlightInfo.sq[i].x >= 0 && highlightInfo.sq[i].y >= 0) {\r
- SquareToPos(highlightInfo.sq[i].y, highlightInfo.sq[i].x, &x, &y);\r
- clips[num_clips++] =\r
- CreateRectRgn(x - lineGap, y - lineGap, \r
- x + squareSize + lineGap, y + squareSize + lineGap);\r
- }\r
+ lastDrawnHighlight.sq[i].y != highlightInfo.sq[i].y) {\r
+ if (lastDrawnHighlight.sq[i].x >= 0 &&\r
+ lastDrawnHighlight.sq[i].y >= 0) {\r
+ SquareToPos(lastDrawnHighlight.sq[i].y,\r
+ lastDrawnHighlight.sq[i].x, &x, &y);\r
+ clips[num_clips++] =\r
+ CreateRectRgn(x - lineGap, y - lineGap,\r
+ x + squareSize + lineGap, y + squareSize + lineGap);\r
+ }\r
+ if (highlightInfo.sq[i].x >= 0 && highlightInfo.sq[i].y >= 0) {\r
+ SquareToPos(highlightInfo.sq[i].y, highlightInfo.sq[i].x, &x, &y);\r
+ clips[num_clips++] =\r
+ CreateRectRgn(x - lineGap, y - lineGap,\r
+ x + squareSize + lineGap, y + squareSize + lineGap);\r
+ }\r
}\r
}\r
for (i=0; i<2; i++) {\r
if (lastDrawnPremove.sq[i].x != premoveHighlightInfo.sq[i].x ||\r
- lastDrawnPremove.sq[i].y != premoveHighlightInfo.sq[i].y) {\r
- if (lastDrawnPremove.sq[i].x >= 0 &&\r
- lastDrawnPremove.sq[i].y >= 0) {\r
- SquareToPos(lastDrawnPremove.sq[i].y,\r
- lastDrawnPremove.sq[i].x, &x, &y);\r
- clips[num_clips++] =\r
- CreateRectRgn(x - lineGap, y - lineGap, \r
- x + squareSize + lineGap, y + squareSize + lineGap);\r
- }\r
- if (premoveHighlightInfo.sq[i].x >= 0 && \r
- premoveHighlightInfo.sq[i].y >= 0) {\r
- SquareToPos(premoveHighlightInfo.sq[i].y, \r
- premoveHighlightInfo.sq[i].x, &x, &y);\r
- clips[num_clips++] =\r
- CreateRectRgn(x - lineGap, y - lineGap, \r
- x + squareSize + lineGap, y + squareSize + lineGap);\r
- }\r
+ lastDrawnPremove.sq[i].y != premoveHighlightInfo.sq[i].y) {\r
+ if (lastDrawnPremove.sq[i].x >= 0 &&\r
+ lastDrawnPremove.sq[i].y >= 0) {\r
+ SquareToPos(lastDrawnPremove.sq[i].y,\r
+ lastDrawnPremove.sq[i].x, &x, &y);\r
+ clips[num_clips++] =\r
+ CreateRectRgn(x - lineGap, y - lineGap,\r
+ x + squareSize + lineGap, y + squareSize + lineGap);\r
+ }\r
+ if (premoveHighlightInfo.sq[i].x >= 0 &&\r
+ premoveHighlightInfo.sq[i].y >= 0) {\r
+ SquareToPos(premoveHighlightInfo.sq[i].y,\r
+ premoveHighlightInfo.sq[i].x, &x, &y);\r
+ clips[num_clips++] =\r
+ CreateRectRgn(x - lineGap, y - lineGap,\r
+ x + squareSize + lineGap, y + squareSize + lineGap);\r
+ }\r
}\r
}\r
} else {\r
*/\r
GetClientRect(hwndMain, &Rect);\r
bufferBitmap = CreateCompatibleBitmap(hdc, Rect.right-Rect.left+1,\r
- Rect.bottom-Rect.top+1);\r
+ Rect.bottom-Rect.top+1);\r
oldBitmap = SelectObject(hdcmem, bufferBitmap);\r
if (!appData.monoMode) {\r
SelectPalette(hdcmem, hPal, FALSE);\r
}\r
}\r
\r
- /* If dragging is in progress, we temporarely remove the piece */\r
- if (dragInfo.from.x >= 0 && dragInfo.pos.x >= 0) {\r
- dragged_piece = board[dragInfo.from.y][dragInfo.from.x];\r
- board[dragInfo.from.y][dragInfo.from.x] = EmptySquare;\r
- }\r
-\r
- /* Are we animating a move? \r
- * If so, \r
+ /* Are we animating a move?\r
+ * If so,\r
* - remove the piece from the board (temporarely)\r
* - calculate the clipping region\r
*/\r
y2 = boardRect.top + animInfo.pos.y;\r
clips[num_clips++] = CreateRectRgn(MIN(x,x2), MIN(y,y2), MAX(x,x2)+squareSize, MAX(y,y2)+squareSize);\r
/* Slight kludge. The real problem is that after AnimateMove is\r
- done, the position on the screen does not match lastDrawn.\r
- This currently causes trouble only on e.p. captures in\r
- atomic, where the piece moves to an empty square and then\r
- explodes. The old and new positions both had an empty square\r
- at the destination, but animation has drawn a piece there and\r
- we have to remember to erase it. */\r
+ done, the position on the screen does not match lastDrawn.\r
+ This currently causes trouble only on e.p. captures in\r
+ atomic, where the piece moves to an empty square and then\r
+ explodes. The old and new positions both had an empty square\r
+ at the destination, but animation has drawn a piece there and\r
+ we have to remember to erase it. [HGM] moved until after setting lastDrawn */\r
lastDrawn[animInfo.to.y][animInfo.to.x] = animInfo.piece;\r
}\r
}\r
}\r
\r
/* Do all the drawing to the memory DC */\r
- DrawGridOnDC(hdcmem);\r
- DrawHighlightsOnDC(hdcmem);\r
- DrawBoardOnDC(hdcmem, board, tmphdc);\r
+ if(explodeInfo.radius) { // [HGM] atomic\r
+ HBRUSH oldBrush;\r
+ int x, y, r=(explodeInfo.radius * squareSize)/100;\r
+ board[explodeInfo.fromY][explodeInfo.fromX] = EmptySquare; // suppress display of capturer\r
+ SquareToPos(explodeInfo.toY, explodeInfo.toX, &x, &y);\r
+ x += squareSize/2;\r
+ y += squareSize/2;\r
+ if(!fullrepaint) {\r
+ clips[num_clips] = CreateRectRgn(x-r, y-r, x+r, y+r);\r
+ ExtSelectClipRgn(hdcmem, clips[num_clips++], RGN_OR);\r
+ }\r
+ DrawGridOnDC(hdcmem);\r
+ DrawHighlightsOnDC(hdcmem);\r
+ DrawBoardOnDC(hdcmem, board, tmphdc);\r
+ oldBrush = SelectObject(hdcmem, explodeBrush);\r
+ Ellipse(hdcmem, x-r, y-r, x+r, y+r);\r
+ SelectObject(hdcmem, oldBrush);\r
+ } else {\r
+ DrawGridOnDC(hdcmem);\r
+ DrawHighlightsOnDC(hdcmem);\r
+ DrawBoardOnDC(hdcmem, board, tmphdc);\r
+ }\r
+ if(logoHeight) {\r
+ HBITMAP whiteLogo = (HBITMAP) first.programLogo, blackLogo = (HBITMAP) second.programLogo;\r
+ if(appData.autoLogo) {\r
+\r
+ switch(gameMode) { // pick logos based on game mode\r
+ case IcsObserving:\r
+ whiteLogo = second.programLogo; // ICS logo\r
+ blackLogo = second.programLogo;\r
+ default:\r
+ break;\r
+ case IcsPlayingWhite:\r
+ if(!appData.zippyPlay) whiteLogo = userLogo;\r
+ blackLogo = second.programLogo; // ICS logo\r
+ break;\r
+ case IcsPlayingBlack:\r
+ whiteLogo = second.programLogo; // ICS logo\r
+ blackLogo = appData.zippyPlay ? first.programLogo : userLogo;\r
+ break;\r
+ case TwoMachinesPlay:\r
+ if(first.twoMachinesColor[0] == 'b') {\r
+ whiteLogo = second.programLogo;\r
+ blackLogo = first.programLogo;\r
+ }\r
+ break;\r
+ case MachinePlaysWhite:\r
+ blackLogo = userLogo;\r
+ break;\r
+ case MachinePlaysBlack:\r
+ whiteLogo = userLogo;\r
+ blackLogo = first.programLogo;\r
+ }\r
+ }\r
+ DrawLogoOnDC(hdc, leftLogoRect, flipClock ? blackLogo : whiteLogo);\r
+ DrawLogoOnDC(hdc, rightLogoRect, flipClock ? whiteLogo : blackLogo);\r
+ }\r
+\r
+ if( appData.highlightMoveWithArrow ) {\r
+ DrawArrowHighlight(hdcmem);\r
+ }\r
+\r
DrawCoordsOnDC(hdcmem);\r
\r
- /* Put the dragged piece back into place and draw it */\r
- if (dragged_piece != EmptySquare) {\r
+ CopyBoard(lastDrawn, board); /* [HGM] Moved to here from end of routine, */\r
+ /* to make sure lastDrawn contains what is actually drawn */\r
+\r
+ /* Put the dragged piece back into place and draw it (out of place!) */\r
+ if (dragged_piece != EmptySquare) {\r
+ /* [HGM] or restack */\r
+ if(dragInfo.from.x == BOARD_LEFT-2 )\r
+ board[dragInfo.from.y][dragInfo.from.x+1]++;\r
+ else\r
+ if(dragInfo.from.x == BOARD_RGHT+1 )\r
+ board[dragInfo.from.y][dragInfo.from.x-1]++;\r
board[dragInfo.from.y][dragInfo.from.x] = dragged_piece;\r
x = dragInfo.pos.x - squareSize / 2;\r
y = dragInfo.pos.y - squareSize / 2;\r
DrawPieceOnDC(hdcmem, dragged_piece,\r
- ((int) dragged_piece < (int) BlackPawn), \r
+ ((int) dragged_piece < (int) BlackPawn),\r
(dragInfo.from.y + dragInfo.from.x) % 2, x, y, tmphdc);\r
- } \r
- \r
+ }\r
+\r
/* Put the animated piece back into place and draw it */\r
if (animInfo.piece != EmptySquare) {\r
board[animInfo.from.y][animInfo.from.x] = animInfo.piece;\r
x = boardRect.left + animInfo.pos.x;\r
y = boardRect.top + animInfo.pos.y;\r
DrawPieceOnDC(hdcmem, animInfo.piece,\r
- ((int) animInfo.piece < (int) BlackPawn),\r
+ ((int) animInfo.piece < (int) BlackPawn),\r
(animInfo.from.y + animInfo.from.x) % 2, x, y, tmphdc);\r
}\r
\r
- /* Release the bufferBitmap by selecting in the old bitmap \r
+ /* Release the bufferBitmap by selecting in the old bitmap\r
* and delete the memory DC\r
*/\r
SelectObject(hdcmem, oldBitmap);\r
for (x = 1; x < num_clips; x++) {\r
if (ExtSelectClipRgn(hdc, clips[x], RGN_OR) == ERROR)\r
abort(); // this should never ever happen!\r
- } \r
+ }\r
}\r
\r
/* Copy the new bitmap onto the screen in one go.\r
*/\r
oldBitmap = SelectObject(tmphdc, bufferBitmap);\r
BitBlt(hdc, boardRect.left, boardRect.top,\r
- boardRect.right - boardRect.left,\r
- boardRect.bottom - boardRect.top,\r
- tmphdc, boardRect.left, boardRect.top, SRCCOPY);\r
+ boardRect.right - boardRect.left,\r
+ boardRect.bottom - boardRect.top,\r
+ tmphdc, boardRect.left, boardRect.top, SRCCOPY);\r
+ if(saveDiagFlag) {\r
+ BITMAP b; int i, j=0, m, w, wb, fac=0; char pData[1000000];\r
+ BITMAPINFOHEADER bih; int color[16], nrColors=0;\r
+\r
+ GetObject(bufferBitmap, sizeof(b), &b);\r
+ if(b.bmWidthBytes*b.bmHeight <= 990000) {\r
+ bih.biSize = sizeof(BITMAPINFOHEADER);\r
+ bih.biWidth = b.bmWidth;\r
+ bih.biHeight = b.bmHeight;\r
+ bih.biPlanes = 1;\r
+ bih.biBitCount = b.bmBitsPixel;\r
+ bih.biCompression = 0;\r
+ bih.biSizeImage = b.bmWidthBytes*b.bmHeight;\r
+ bih.biXPelsPerMeter = 0;\r
+ bih.biYPelsPerMeter = 0;\r
+ bih.biClrUsed = 0;\r
+ bih.biClrImportant = 0;\r
+// fprintf(diagFile, "t=%d\nw=%d\nh=%d\nB=%d\nP=%d\nX=%d\n",\r
+// b.bmType, b.bmWidth, b.bmHeight, b.bmWidthBytes, b.bmPlanes, b.bmBitsPixel);\r
+ GetDIBits(tmphdc,bufferBitmap,0,b.bmHeight,pData,(BITMAPINFO*)&bih,DIB_RGB_COLORS);\r
+// fprintf(diagFile, "%8x\n", (int) pData);\r
+\r
+#if 1\r
+ wb = b.bmWidthBytes;\r
+ // count colors\r
+ for(i=0; i<wb*(b.bmHeight - boardRect.top + OUTER_MARGIN)>>2; i++) {\r
+ int k = ((int*) pData)[i];\r
+ for(j=0; j<nrColors; j++) if(color[j] == k) break;\r
+ if(j >= 16) break;\r
+ color[j] = k;\r
+ if(j >= nrColors) nrColors = j+1;\r
+ }\r
+ if(j<16) { // 16 colors is enough. Compress to 4 bits per pixel\r
+ INT p = 0;\r
+ for(i=0; i<b.bmHeight - boardRect.top + OUTER_MARGIN; i++) {\r
+ for(w=0; w<(wb>>2); w+=2) {\r
+ int k = ((int*) pData)[(wb*i>>2) + w];\r
+ for(j=0; j<nrColors; j++) if(color[j] == k) break;\r
+ k = ((int*) pData)[(wb*i>>2) + w + 1];\r
+ for(m=0; m<nrColors; m++) if(color[m] == k) break;\r
+ pData[p++] = m | j<<4;\r
+ }\r
+ while(p&3) pData[p++] = 0;\r
+ }\r
+ fac = 3;\r
+ wb = ((wb+31)>>5)<<2;\r
+ }\r
+ // write BITMAPFILEHEADER\r
+ fprintf(diagFile, "BM");\r
+ fputDW(diagFile, wb*(b.bmHeight - boardRect.top + OUTER_MARGIN)+0x36 + (fac?64:0));\r
+ fputDW(diagFile, 0);\r
+ fputDW(diagFile, 0x36 + (fac?64:0));\r
+ // write BITMAPINFOHEADER\r
+ fputDW(diagFile, 40);\r
+ fputDW(diagFile, b.bmWidth);\r
+ fputDW(diagFile, b.bmHeight - boardRect.top + OUTER_MARGIN);\r
+ if(fac) fputDW(diagFile, 0x040001); // planes and bits/pixel\r
+ else fputDW(diagFile, 0x200001); // planes and bits/pixel\r
+ fputDW(diagFile, 0);\r
+ fputDW(diagFile, 0);\r
+ fputDW(diagFile, 0);\r
+ fputDW(diagFile, 0);\r
+ fputDW(diagFile, 0);\r
+ fputDW(diagFile, 0);\r
+ // write color table\r
+ if(fac)\r
+ for(i=0; i<16; i++) fputDW(diagFile, color[i]);\r
+ // write bitmap data\r
+ for(i=0; i<wb*(b.bmHeight - boardRect.top + OUTER_MARGIN); i++)\r
+ fputc(pData[i], diagFile);\r
+#endif\r
+ }\r
+ }\r
+\r
SelectObject(tmphdc, oldBitmap);\r
\r
/* Massive cleanup */\r
DeleteDC(tmphdc);\r
DeleteObject(bufferBitmap);\r
\r
- if (releaseDC) \r
+ if (releaseDC)\r
ReleaseDC(hwndMain, hdc);\r
- \r
+\r
if (lastDrawnFlipView != flipView) {\r
if (flipView)\r
CheckMenuItem(GetMenu(hwndMain),IDM_FlipView, MF_BYCOMMAND|MF_CHECKED);\r
CheckMenuItem(GetMenu(hwndMain),IDM_FlipView, MF_BYCOMMAND|MF_UNCHECKED);\r
}\r
\r
- CopyBoard(lastDrawn, board);\r
+/* CopyBoard(lastDrawn, board);*/\r
lastDrawnHighlight = highlightInfo;\r
lastDrawnPremove = premoveHighlightInfo;\r
lastDrawnFlipView = flipView;\r
lastDrawnValid = 1;\r
}\r
\r
+/* [HGM] diag: Save the current board display to the given open file and close the file */\r
+int\r
+SaveDiagram(f)\r
+ FILE *f;\r
+{\r
+ saveDiagFlag = 1; diagFile = f;\r
+ HDCDrawPosition(NULL, TRUE, NULL);\r
+\r
+ saveDiagFlag = 0;\r
+\r
+// if(f != NULL) fprintf(f, "Sorry, but this feature is still in preparation\n");\r
+\r
+ fclose(f);\r
+ return TRUE;\r
+}\r
+\r
\r
/*---------------------------------------------------------------------------*\\r
| CLIENT PAINT PROCEDURE\r
PAINTSTRUCT ps;\r
HFONT oldFont;\r
\r
- if(hdc = BeginPaint(hwnd, &ps)) {\r
+ if((hdc = BeginPaint(hwnd, &ps))) {\r
if (IsIconic(hwnd)) {\r
DrawIcon(hdc, 2, 2, iconCurrent);\r
} else {\r
if (!appData.monoMode) {\r
- SelectPalette(hdc, hPal, FALSE);\r
- RealizePalette(hdc);\r
+ SelectPalette(hdc, hPal, FALSE);\r
+ RealizePalette(hdc);\r
}\r
HDCDrawPosition(hdc, 1, NULL);\r
oldFont =\r
- SelectObject(hdc, font[boardSize][MESSAGE_FONT]->hf);\r
+ SelectObject(hdc, font[boardSize][MESSAGE_FONT]->hf);\r
ExtTextOut(hdc, messageRect.left, messageRect.top,\r
- ETO_CLIPPED|ETO_OPAQUE,\r
- &messageRect, messageText, strlen(messageText), NULL);\r
+ ETO_CLIPPED|ETO_OPAQUE,\r
+ &messageRect, messageText, strlen(messageText), NULL);\r
SelectObject(hdc, oldFont);\r
DisplayBothClocks();\r
}\r
\r
for (i=0; i<sizeof(dropEnables)/sizeof(DropEnable); i++) {\r
p = strchr(gameMode == IcsPlayingWhite ? white_holding : black_holding,\r
- dropEnables[i].piece);\r
+ dropEnables[i].piece);\r
count = 0;\r
while (p && *p++ == dropEnables[i].piece) count++;\r
sprintf(item, "%s %d", dropEnables[i].name, count);\r
enable = count > 0 || !appData.testLegality\r
/*!!temp:*/ || (gameInfo.variant == VariantCrazyhouse\r
- && !appData.icsActive);\r
+ && !appData.icsActive);\r
ModifyMenu(hmenu, dropEnables[i].command,\r
- MF_BYCOMMAND | (enable ? MF_ENABLED : MF_GRAYED) | MF_STRING,\r
- dropEnables[i].command, item);\r
+ MF_BYCOMMAND | (enable ? MF_ENABLED : MF_GRAYED) | MF_STRING,\r
+ dropEnables[i].command, item);\r
}\r
}\r
\r
-static int fromX = -1, fromY = -1, toX, toY;\r
-\r
/* Event handler for mouse messages */\r
VOID\r
MouseEvent(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)\r
POINT pt;\r
static int recursive = 0;\r
HMENU hmenu;\r
+// BOOLEAN needsRedraw = FALSE;\r
BOOLEAN saveAnimate;\r
- static BOOLEAN sameAgain = FALSE;\r
+ BOOLEAN forceFullRepaint = IsFullRepaintPreferrable(); /* [AS] */\r
+ static BOOLEAN sameAgain = FALSE, promotionChoice = FALSE;\r
+ ChessMove moveType;\r
\r
if (recursive) {\r
if (message == WM_MBUTTONUP) {\r
/* Hideous kludge to fool TrackPopupMenu into paying attention\r
- to the middle button: we simulate pressing the left button too!\r
- */\r
+ to the middle button: we simulate pressing the left button too!\r
+ */\r
PostMessage(hwnd, WM_LBUTTONDOWN, wParam, lParam);\r
PostMessage(hwnd, WM_LBUTTONUP, wParam, lParam);\r
}\r
return;\r
}\r
recursive++;\r
- \r
+\r
pt.x = LOWORD(lParam);\r
pt.y = HIWORD(lParam);\r
x = EventToSquare(pt.x - boardRect.left);\r
y = EventToSquare(pt.y - boardRect.top);\r
if (!flipView && y >= 0) {\r
- y = BOARD_SIZE - 1 - y;\r
+ y = BOARD_HEIGHT - 1 - y;\r
}\r
if (flipView && x >= 0) {\r
- x = BOARD_SIZE - 1 - x;\r
+ x = BOARD_WIDTH - 1 - x;\r
}\r
\r
switch (message) {\r
case WM_LBUTTONDOWN:\r
+ if(promotionChoice) { // we are waiting for a click to indicate promotion piece\r
+ promotionChoice = FALSE; // only one chance: if click not OK it is interpreted as cancel\r
+ if(appData.debugMode) fprintf(debugFP, "promotion click, x=%d, y=%d\n", x, y);\r
+ if(gameInfo.holdingsWidth &&\r
+ (WhiteOnMove(currentMove)\r
+ ? x == BOARD_WIDTH-1 && y < gameInfo.holdingsSize && y > 0\r
+ : x == 0 && y >= BOARD_HEIGHT - gameInfo.holdingsSize && y < BOARD_HEIGHT-1) ) {\r
+ // click in right holdings, for determining promotion piece\r
+ ChessSquare p = boards[currentMove][y][x];\r
+ if(appData.debugMode) fprintf(debugFP, "square contains %d\n", (int)p);\r
+ if(p != EmptySquare) {\r
+ FinishMove(WhitePromotionQueen, fromX, fromY, toX, toY, ToLower(PieceToChar(p)));\r
+ fromX = fromY = -1;\r
+ break;\r
+ }\r
+ }\r
+ DrawPosition(FALSE, boards[currentMove]);\r
+ break;\r
+ }\r
ErrorPopDown();\r
sameAgain = FALSE;\r
if (y == -2) {\r
/* Downclick vertically off board; check if on clock */\r
if (PtInRect((LPRECT) &whiteRect, pt)) {\r
- if (gameMode == EditPosition) {\r
- SetWhiteToPlayEvent();\r
- } else if (gameMode == IcsPlayingBlack ||\r
- gameMode == MachinePlaysWhite) {\r
- CallFlagEvent();\r
- }\r
+ if (gameMode == EditPosition) {\r
+ SetWhiteToPlayEvent();\r
+ } else if (gameMode == IcsPlayingBlack ||\r
+ gameMode == MachinePlaysWhite) {\r
+ CallFlagEvent();\r
+ } else if (gameMode == EditGame) {\r
+ AdjustClock(flipClock, -1);\r
+ }\r
} else if (PtInRect((LPRECT) &blackRect, pt)) {\r
- if (gameMode == EditPosition) {\r
- SetBlackToPlayEvent();\r
- } else if (gameMode == IcsPlayingWhite ||\r
- gameMode == MachinePlaysBlack) {\r
- CallFlagEvent();\r
- }\r
+ if (gameMode == EditPosition) {\r
+ SetBlackToPlayEvent();\r
+ } else if (gameMode == IcsPlayingWhite ||\r
+ gameMode == MachinePlaysBlack) {\r
+ CallFlagEvent();\r
+ } else if (gameMode == EditGame) {\r
+ AdjustClock(!flipClock, -1);\r
+ }\r
}\r
if (!appData.highlightLastMove) {\r
ClearHighlights();\r
- DrawPosition(FALSE, NULL);\r
+ DrawPosition((int) (forceFullRepaint || FALSE), NULL);\r
}\r
fromX = fromY = -1;\r
dragInfo.start.x = dragInfo.start.y = -1;\r
dragInfo.from = dragInfo.start;\r
break;\r
- } else if (x < 0 || y < 0) {\r
+ } else if (x < 0 || y < 0\r
+ /* [HGM] block clicks between board and holdings */\r
+ || x == BOARD_LEFT-1 || x == BOARD_RGHT\r
+ || (x == BOARD_LEFT-2 && y < BOARD_HEIGHT-gameInfo.holdingsSize)\r
+ || (x == BOARD_RGHT+1 && y >= gameInfo.holdingsSize)\r
+ /* EditPosition, empty square, or different color piece;\r
+ click-click move is possible */\r
+ ) {\r
break;\r
} else if (fromX == x && fromY == y) {\r
/* Downclick on same square again */\r
ClearHighlights();\r
- DrawPosition(FALSE, NULL);\r
- sameAgain = TRUE; \r
- } else if (fromX != -1) {\r
- /* Downclick on different square */\r
- ChessSquare pdown, pup;\r
- pdown = boards[currentMove][fromY][fromX];\r
- pup = boards[currentMove][y][x];\r
- if (gameMode == EditPosition ||\r
- !((WhitePawn <= pdown && pdown <= WhiteKing &&\r
- WhitePawn <= pup && pup <= WhiteKing) ||\r
- (BlackPawn <= pdown && pdown <= BlackKing &&\r
- BlackPawn <= pup && pup <= BlackKing))) {\r
- /* EditPosition, empty square, or different color piece;\r
- click-click move is possible */\r
- toX = x;\r
- toY = y;\r
- if (IsPromotion(fromX, fromY, toX, toY)) {\r
- if (appData.alwaysPromoteToQueen) {\r
- UserMoveEvent(fromX, fromY, toX, toY, 'q');\r
- if (!appData.highlightLastMove) {\r
- ClearHighlights();\r
- DrawPosition(FALSE, NULL);\r
- }\r
- } else {\r
- SetHighlights(fromX, fromY, toX, toY);\r
- DrawPosition(FALSE, NULL);\r
- PromotionPopup(hwnd);\r
- }\r
- } else { /* not a promotion */\r
- if (appData.animate || appData.highlightLastMove) {\r
- SetHighlights(fromX, fromY, toX, toY);\r
- } else {\r
- ClearHighlights();\r
- }\r
- UserMoveEvent(fromX, fromY, toX, toY, NULLCHAR);\r
- if (appData.animate && !appData.highlightLastMove) {\r
- ClearHighlights();\r
- DrawPosition(FALSE, NULL);\r
- }\r
- }\r
- if (gotPremove) SetPremoveHighlights(fromX, fromY, toX, toY);\r
- fromX = fromY = -1;\r
- break;\r
- }\r
- ClearHighlights();\r
- DrawPosition(FALSE, NULL);\r
+ DrawPosition(forceFullRepaint || FALSE, NULL);\r
+ sameAgain = TRUE;\r
+ } else if (fromX != -1 &&\r
+ x != BOARD_LEFT-2 && x != BOARD_RGHT+1\r
+ ) {\r
+ /* Downclick on different square. */\r
+ /* [HGM] if on holdings file, should count as new first click ! */\r
+ /* [HGM] <sameColor> now always do UserMoveTest(), and check colors there */\r
+ toX = x;\r
+ toY = y;\r
+ /* [HGM] <popupFix> UserMoveEvent requires two calls now,\r
+ to make sure move is legal before showing promotion popup */\r
+ moveType = UserMoveTest(fromX, fromY, toX, toY, NULLCHAR, FALSE);\r
+ if(moveType == AmbiguousMove) { /* [HGM] Edit-Position move executed */\r
+ fromX = fromY = -1;\r
+ ClearHighlights();\r
+ DrawPosition(FALSE, boards[currentMove]);\r
+ break;\r
+ } else\r
+ if(moveType != ImpossibleMove && moveType != Comment) {\r
+ /* [HGM] We use PromotionToKnight in Shogi to indicate frorced promotion */\r
+ if (moveType == WhitePromotionKnight || moveType == BlackPromotionKnight ||\r
+ ((moveType == WhitePromotionQueen || moveType == BlackPromotionQueen) &&\r
+ appData.alwaysPromoteToQueen)) {\r
+ FinishMove(moveType, fromX, fromY, toX, toY, 'q');\r
+ if (!appData.highlightLastMove) {\r
+ ClearHighlights();\r
+ DrawPosition(forceFullRepaint || FALSE, NULL);\r
+ }\r
+ } else\r
+ if (moveType == WhitePromotionQueen || moveType == BlackPromotionQueen ) {\r
+ SetHighlights(fromX, fromY, toX, toY);\r
+ DrawPosition(forceFullRepaint || FALSE, NULL);\r
+ /* [HGM] <popupFix> Popup calls FinishMove now.\r
+ If promotion to Q is legal, all are legal! */\r
+ if(gameInfo.variant == VariantSuper || gameInfo.variant == VariantGreat)\r
+ { ChessSquare p = boards[currentMove][fromY][fromX], q = boards[currentMove][toY][toX];\r
+ // kludge to temporarily execute move on display, without promoting yet\r
+ promotionChoice = TRUE;\r
+ boards[currentMove][fromY][fromX] = EmptySquare; // move Pawn to 8th rank\r
+ boards[currentMove][toY][toX] = p;\r
+ DrawPosition(FALSE, boards[currentMove]);\r
+ boards[currentMove][fromY][fromX] = p; // take back, but display stays\r
+ boards[currentMove][toY][toX] = q;\r
+ DisplayMessage("Select piece from holdings", "");\r
+ } else\r
+ PromotionPopup(hwnd);\r
+ goto noClear;\r
+ } else { // not a promotion. Move can be illegal if testLegality off, and should be made then.\r
+ if (appData.animate || appData.highlightLastMove) {\r
+ SetHighlights(fromX, fromY, toX, toY);\r
+ } else {\r
+ ClearHighlights();\r
+ }\r
+ FinishMove(moveType, fromX, fromY, toX, toY, NULLCHAR);\r
+ if (appData.animate && !appData.highlightLastMove) {\r
+ ClearHighlights();\r
+ DrawPosition(forceFullRepaint || FALSE, NULL);\r
+ }\r
+ }\r
+ fromX = fromY = -1;\r
+ noClear:\r
+ break;\r
+ }\r
+ if (gotPremove && moveType != Comment) {\r
+ SetPremoveHighlights(fromX, fromY, toX, toY);\r
+// DrawPosition(forceFullRepaint || FALSE, NULL);\r
+ } else ClearHighlights();\r
+ fromX = fromY = -1;\r
+ DrawPosition(forceFullRepaint || FALSE, NULL);\r
+ if(moveType != Comment) break;\r
}\r
/* First downclick, or restart on a square with same color piece */\r
if (!frozen && OKToStartUserMove(x, y)) {\r
fromX = fromY = -1;\r
dragInfo.start.x = dragInfo.start.y = -1;\r
dragInfo.from = dragInfo.start;\r
+ DrawPosition(forceFullRepaint || FALSE, NULL); /* [AS] */\r
}\r
break;\r
\r
dragInfo.from.x = dragInfo.from.y = -1;\r
/* Upclick on same square */\r
if (sameAgain) {\r
- /* Clicked same square twice: abort click-click move */\r
- fromX = fromY = -1;\r
- gotPremove = 0;\r
- ClearPremoveHighlights();\r
+ /* Clicked same square twice: abort click-click move */\r
+ fromX = fromY = -1;\r
+ gotPremove = 0;\r
+ ClearPremoveHighlights();\r
} else {\r
- /* First square clicked: start click-click move */\r
- SetHighlights(fromX, fromY, -1, -1);\r
+ /* First square clicked: start click-click move */\r
+ SetHighlights(fromX, fromY, -1, -1);\r
}\r
- DrawPosition(FALSE, NULL);\r
+ DrawPosition(forceFullRepaint || FALSE, NULL);\r
} else if (dragInfo.from.x < 0 || dragInfo.from.y < 0) {\r
/* Errant click; ignore */\r
break;\r
} else {\r
- /* Finish drag move */\r
+ /* Finish drag move. */\r
+ if (appData.debugMode) {\r
+ fprintf(debugFP, "release\n");\r
+ }\r
dragInfo.from.x = dragInfo.from.y = -1;\r
toX = x;\r
toY = y;\r
saveAnimate = appData.animate; /* sorry, Hawk :) */\r
appData.animate = appData.animate && !appData.animateDragging;\r
- if (IsPromotion(fromX, fromY, toX, toY)) {\r
- if (appData.alwaysPromoteToQueen) {\r
- UserMoveEvent(fromX, fromY, toX, toY, 'q');\r
- } else {\r
- DrawPosition(FALSE, NULL);\r
- PromotionPopup(hwnd);\r
- }\r
- } else {\r
- UserMoveEvent(fromX, fromY, toX, toY, NULLCHAR);\r
+ moveType = UserMoveTest(fromX, fromY, toX, toY, NULLCHAR, TRUE);\r
+ if(moveType == AmbiguousMove) { /* [HGM] Edit-Position move executed */\r
+ fromX = fromY = -1;\r
+ ClearHighlights();\r
+ DrawPosition(FALSE, boards[currentMove]);\r
+ appData.animate = saveAnimate;\r
+ break;\r
+ } else\r
+ if(moveType != ImpossibleMove) {\r
+ /* [HGM] use move type to determine if move is promotion.\r
+ Knight is Shogi kludge for mandatory promotion, Queen means choice */\r
+ if (moveType == WhitePromotionKnight || moveType == BlackPromotionKnight ||\r
+ ((moveType == WhitePromotionQueen || moveType == BlackPromotionQueen) &&\r
+ appData.alwaysPromoteToQueen))\r
+ FinishMove(moveType, fromX, fromY, toX, toY, 'q');\r
+ else\r
+ if (moveType == WhitePromotionQueen || moveType == BlackPromotionQueen ) {\r
+ DrawPosition(forceFullRepaint || FALSE, NULL);\r
+ if(gameInfo.variant == VariantSuper || gameInfo.variant == VariantGreat)\r
+ { ChessSquare p = boards[currentMove][fromY][fromX], q = boards[currentMove][toY][toX];\r
+ // kludge to temporarily execute move on display, wthout promotng yet\r
+ promotionChoice = TRUE;\r
+ boards[currentMove][fromY][fromX] = EmptySquare; // move Pawn to 8th rank\r
+ boards[currentMove][toY][toX] = p;\r
+ DrawPosition(FALSE, boards[currentMove]);\r
+ boards[currentMove][fromY][fromX] = p; // take back, but display stays\r
+ boards[currentMove][toY][toX] = q;\r
+ appData.animate = saveAnimate;\r
+ DisplayMessage("Select piece from holdings", "");\r
+ break;\r
+ } else\r
+ PromotionPopup(hwnd); /* [HGM] Popup now calls FinishMove */\r
+ } else {\r
+ if(saveAnimate /* ^$!%@#$!$ */ && gameInfo.variant == VariantAtomic\r
+ && (boards[currentMove][toY][toX] != EmptySquare ||\r
+ moveType == WhiteCapturesEnPassant ||\r
+ moveType == BlackCapturesEnPassant ) )\r
+ AnimateAtomicCapture(fromX, fromY, toX, toY, 20);\r
+ FinishMove(moveType, fromX, fromY, toX, toY, NULLCHAR);\r
+ }\r
}\r
if (gotPremove) SetPremoveHighlights(fromX, fromY, toX, toY);\r
appData.animate = saveAnimate;\r
fromX = fromY = -1;\r
if (appData.highlightDragging && !appData.highlightLastMove) {\r
- ClearHighlights();\r
+ ClearHighlights();\r
}\r
if (appData.animate || appData.animateDragging ||\r
- appData.highlightDragging || gotPremove) {\r
- DrawPosition(FALSE, NULL);\r
+ appData.highlightDragging || gotPremove) {\r
+ DrawPosition(forceFullRepaint || FALSE, NULL);\r
}\r
}\r
- dragInfo.start.x = dragInfo.start.y = -1; \r
+ dragInfo.start.x = dragInfo.start.y = -1;\r
dragInfo.pos = dragInfo.lastpos = dragInfo.start;\r
break;\r
\r
case WM_MOUSEMOVE:\r
if ((appData.animateDragging || appData.highlightDragging)\r
- && (wParam & MK_LBUTTON)\r
- && dragInfo.from.x >= 0) {\r
+ && (wParam & MK_LBUTTON)\r
+ && dragInfo.from.x >= 0)\r
+ {\r
+ BOOL full_repaint = FALSE;\r
+\r
+ sameAgain = FALSE; /* [HGM] if we drag something around, do keep square selected */\r
if (appData.animateDragging) {\r
- dragInfo.pos = pt;\r
+ dragInfo.pos = pt;\r
}\r
if (appData.highlightDragging) {\r
- SetHighlights(fromX, fromY, x, y);\r
+ SetHighlights(fromX, fromY, x, y);\r
+ if( IsDrawArrowEnabled() && (x < 0 || x >= BOARD_WIDTH || y < 0 || y >= BOARD_HEIGHT) ) {\r
+ full_repaint = TRUE;\r
+ }\r
}\r
- DrawPosition(FALSE, NULL);\r
+\r
+ DrawPosition( full_repaint, NULL);\r
+\r
dragInfo.lastpos = dragInfo.pos;\r
}\r
break;\r
\r
+ case WM_MOUSEWHEEL: // [DM]\r
+ { static int lastDir = 0; // [HGM] build in some hysteresis to avoid spurious events\r
+ /* Mouse Wheel is being rolled forward\r
+ * Play moves forward\r
+ */\r
+ if((short)HIWORD(wParam) > 0 && currentMove < forwardMostMove)\r
+ { if(lastDir == 1) ForwardEvent(); else lastDir = 1; } // [HGM] suppress first event in direction\r
+ /* Mouse Wheel is being rolled backward\r
+ * Play moves backward\r
+ */\r
+ if((short)HIWORD(wParam) < 0 && currentMove > backwardMostMove)\r
+ { if(lastDir == -1) BackwardEvent(); else lastDir = -1; }\r
+ }\r
+ break;\r
+\r
case WM_MBUTTONDOWN:\r
case WM_RBUTTONDOWN:\r
ErrorPopDown();\r
if (appData.highlightDragging) {\r
ClearHighlights();\r
}\r
+ if(y == -2) {\r
+ /* [HGM] right mouse button in clock area edit-game mode ups clock */\r
+ if (PtInRect((LPRECT) &whiteRect, pt)) {\r
+ if (gameMode == EditGame) AdjustClock(flipClock, 1);\r
+ } else if (PtInRect((LPRECT) &blackRect, pt)) {\r
+ if (gameMode == EditGame) AdjustClock(!flipClock, 1);\r
+ }\r
+ }\r
DrawPosition(TRUE, NULL);\r
\r
switch (gameMode) {\r
fromX = x;\r
fromY = y;\r
if (message == WM_MBUTTONDOWN) {\r
- buttonCount = 3; /* even if system didn't think so */\r
- if (wParam & MK_SHIFT) \r
- MenuPopup(hwnd, pt, LoadMenu(hInst, "BlackPieceMenu"), -1);\r
- else\r
- MenuPopup(hwnd, pt, LoadMenu(hInst, "WhitePieceMenu"), -1);\r
+ buttonCount = 3; /* even if system didn't think so */\r
+ if (wParam & MK_SHIFT)\r
+ MenuPopup(hwnd, pt, LoadMenu(hInst, "BlackPieceMenu"), -1);\r
+ else\r
+ MenuPopup(hwnd, pt, LoadMenu(hInst, "WhitePieceMenu"), -1);\r
} else { /* message == WM_RBUTTONDOWN */\r
#if 0\r
- if (buttonCount == 3) {\r
- if (wParam & MK_SHIFT) \r
- MenuPopup(hwnd, pt, LoadMenu(hInst, "WhitePieceMenu"), -1);\r
- else\r
- MenuPopup(hwnd, pt, LoadMenu(hInst, "BlackPieceMenu"), -1);\r
- } else {\r
- MenuPopup(hwnd, pt, LoadMenu(hInst, "PieceMenu"), -1);\r
- }\r
+ if (buttonCount == 3) {\r
+ if (wParam & MK_SHIFT)\r
+ MenuPopup(hwnd, pt, LoadMenu(hInst, "WhitePieceMenu"), -1);\r
+ else\r
+ MenuPopup(hwnd, pt, LoadMenu(hInst, "BlackPieceMenu"), -1);\r
+ } else {\r
+ MenuPopup(hwnd, pt, LoadMenu(hInst, "PieceMenu"), -1);\r
+ }\r
#else\r
- /* Just have one menu, on the right button. Windows users don't\r
- think to try the middle one, and sometimes other software steals\r
- it, or it doesn't really exist. */\r
- MenuPopup(hwnd, pt, LoadMenu(hInst, "PieceMenu"), -1);\r
+ /* Just have one menu, on the right button. Windows users don't\r
+ think to try the middle one, and sometimes other software steals\r
+ it, or it doesn't really exist. */\r
+ if(gameInfo.variant != VariantShogi)\r
+ MenuPopup(hwnd, pt, LoadMenu(hInst, "PieceMenu"), -1);\r
+ else\r
+ MenuPopup(hwnd, pt, LoadMenu(hInst, "ShogiPieceMenu"), -1);\r
#endif\r
}\r
break;\r
case MachinePlaysWhite:\r
case MachinePlaysBlack:\r
if (appData.testLegality &&\r
- gameInfo.variant != VariantBughouse &&\r
- gameInfo.variant != VariantCrazyhouse) break;\r
+ gameInfo.variant != VariantBughouse &&\r
+ gameInfo.variant != VariantCrazyhouse) break;\r
if (x < 0 || y < 0) break;\r
fromX = x;\r
fromY = y;\r
case '\r':\r
SendMessage(hwndMain, WM_COMMAND, MAKEWPARAM(buttonDesc[i].id, 0), 0);\r
return TRUE;\r
- case '\t':\r
- if (appData.icsActive) {\r
- if (GetKeyState(VK_SHIFT) < 0) {\r
- /* shifted */\r
- HWND h = GetDlgItem(hwndConsole, OPT_ConsoleInput);\r
- if (IsIconic(hwndConsole)) ShowWindow(hwndConsole, SW_RESTORE);\r
- SetFocus(h);\r
- } else {\r
- /* unshifted */\r
- HWND h = GetDlgItem(hwndConsole, OPT_ConsoleText);\r
- if (IsIconic(hwndConsole)) ShowWindow(hwndConsole, SW_RESTORE);\r
- SetFocus(h);\r
- }\r
- return TRUE;\r
- }\r
- break;\r
default:\r
- if (appData.icsActive) {\r
+ if (appData.icsActive && (isalpha((char)wParam) || wParam == '0')) {\r
+ // [HGM] movenum: only letters or leading zero should go to ICS input\r
HWND h = GetDlgItem(hwndConsole, OPT_ConsoleInput);\r
- if (IsIconic(hwndConsole)) ShowWindow(hwndConsole, SW_RESTORE);\r
- SetFocus(h);\r
- SendMessage(h, WM_CHAR, wParam, lParam);\r
- return TRUE;\r
+ if (IsIconic(hwndConsole)) ShowWindow(hwndConsole, SW_RESTORE);\r
+ SetFocus(h);\r
+ SendMessage(h, WM_CHAR, wParam, lParam);\r
+ return TRUE;\r
} else if (isalpha((char)wParam) || isdigit((char)wParam)){\r
- PopUpMoveDialog((char)wParam);\r
+ PopUpMoveDialog((char)wParam);\r
}\r
break;\r
}\r
case WM_INITDIALOG: /* message: initialize dialog box */\r
/* Center the dialog over the application window */\r
CenterWindow(hDlg, GetWindow(hDlg, GW_OWNER));\r
- ShowWindow(GetDlgItem(hDlg, PB_King), \r
+ ShowWindow(GetDlgItem(hDlg, PB_King),\r
(!appData.testLegality || gameInfo.variant == VariantSuicide ||\r
- gameInfo.variant == VariantGiveaway) ?\r
- SW_SHOW : SW_HIDE);\r
+ gameInfo.variant == VariantGiveaway || gameInfo.variant == VariantSuper ) ?\r
+ SW_SHOW : SW_HIDE);\r
+ /* [HGM] Only allow C & A promotions if these pieces are defined */\r
+ ShowWindow(GetDlgItem(hDlg, PB_Archbishop),\r
+ ((PieceToChar(WhiteAngel) >= 'A' &&\r
+ PieceToChar(WhiteAngel) != '~') ||\r
+ (PieceToChar(BlackAngel) >= 'A' &&\r
+ PieceToChar(BlackAngel) != '~') ) ?\r
+ SW_SHOW : SW_HIDE);\r
+ ShowWindow(GetDlgItem(hDlg, PB_Chancellor),\r
+ ((PieceToChar(WhiteMarshall) >= 'A' &&\r
+ PieceToChar(WhiteMarshall) != '~') ||\r
+ (PieceToChar(BlackMarshall) >= 'A' &&\r
+ PieceToChar(BlackMarshall) != '~') ) ?\r
+ SW_SHOW : SW_HIDE);\r
+ /* [HGM] Hide B & R button in Shogi, use Q as promote, N as defer */\r
+ ShowWindow(GetDlgItem(hDlg, PB_Rook),\r
+ gameInfo.variant != VariantShogi ?\r
+ SW_SHOW : SW_HIDE);\r
+ ShowWindow(GetDlgItem(hDlg, PB_Bishop),\r
+ gameInfo.variant != VariantShogi ?\r
+ SW_SHOW : SW_HIDE);\r
+ ShowWindow(GetDlgItem(hDlg, IDC_Yes),\r
+ gameInfo.variant == VariantShogi ?\r
+ SW_SHOW : SW_HIDE);\r
+ ShowWindow(GetDlgItem(hDlg, IDC_No),\r
+ gameInfo.variant == VariantShogi ?\r
+ SW_SHOW : SW_HIDE);\r
+ ShowWindow(GetDlgItem(hDlg, IDC_Centaur),\r
+ gameInfo.variant == VariantSuper ?\r
+ SW_SHOW : SW_HIDE);\r
return TRUE;\r
\r
case WM_COMMAND: /* message: received a command */\r
DrawPosition(FALSE, NULL);\r
return TRUE;\r
case PB_King:\r
- promoChar = 'k';\r
+ promoChar = gameInfo.variant == VariantSuper ? PieceToChar(BlackSilver) : PieceToChar(BlackKing);\r
break;\r
case PB_Queen:\r
- promoChar = 'q';\r
+ promoChar = gameInfo.variant == VariantShogi ? '+' : PieceToChar(BlackQueen);\r
break;\r
case PB_Rook:\r
- promoChar = 'r';\r
+ promoChar = PieceToChar(BlackRook);\r
break;\r
case PB_Bishop:\r
- promoChar = 'b';\r
+ promoChar = PieceToChar(BlackBishop);\r
+ break;\r
+ case PB_Chancellor:\r
+ promoChar = PieceToChar(BlackMarshall);\r
+ break;\r
+ case PB_Archbishop:\r
+ promoChar = PieceToChar(BlackAngel);\r
break;\r
case PB_Knight:\r
- promoChar = 'n';\r
+ promoChar = gameInfo.variant == VariantShogi ? '=' : PieceToChar(BlackKnight);\r
break;\r
default:\r
return FALSE;\r
}\r
EndDialog(hDlg, TRUE); /* Exit the dialog */\r
- UserMoveEvent(fromX, fromY, toX, toY, promoChar);\r
+ /* [HGM] <popupFix> Call FinishMove rather than UserMoveEvent, as we\r
+ only show the popup when we are already sure the move is valid or\r
+ legal. We pass a faulty move type, but the kludge is that FinishMove\r
+ will figure out it is a promotion from the promoChar. */\r
+ FinishMove(NormalMove, fromX, fromY, toX, toY, promoChar);\r
if (!appData.highlightLastMove) {\r
ClearHighlights();\r
DrawPosition(FALSE, NULL);\r
VOID\r
ToggleShowThinking()\r
{\r
- ShowThinkingEvent(!appData.showThinking);\r
+ appData.showThinking = !appData.showThinking;\r
+ ShowThinkingEvent();\r
}\r
\r
VOID\r
UINT number = 0;\r
FILE *f;\r
char fileTitle[MSG_SIZ];\r
- f = OpenFileDialog(hwnd, FALSE, "",\r
- appData.oldSaveStyle ? "gam" : "pgn",\r
- GAME_FILT,\r
- title, &number, fileTitle, NULL);\r
+ f = OpenFileDialog(hwnd, "rb", "",\r
+ appData.oldSaveStyle ? "gam" : "pgn",\r
+ GAME_FILT,\r
+ title, &number, fileTitle, NULL);\r
if (f != NULL) {\r
cmailMsgLoaded = FALSE;\r
if (number == 0) {\r
DisplayError("Cannot build game list", error);\r
} else if (!ListEmpty(&gameList) &&\r
((ListGame *) gameList.tailPred)->number > 1) {\r
- GameListPopUp(f, fileTitle);\r
+ GameListPopUp(f, fileTitle);\r
return;\r
}\r
GameListDestroy();\r
cfmt.yHeight = (int)(f->mfp.pointSize * 20.0 + 0.5);\r
cfmt.bCharSet = f->lf.lfCharSet;\r
cfmt.bPitchAndFamily = f->lf.lfPitchAndFamily;\r
- SendMessage(hText, EM_SETCHARFORMAT, SCF_ALL, (LPARAM) &cfmt); \r
- SendMessage(hInput, EM_SETCHARFORMAT, SCF_ALL, (LPARAM) &cfmt); \r
+ SendMessage(hText, EM_SETCHARFORMAT, SCF_ALL, (LPARAM) &cfmt);\r
+ SendMessage(hInput, EM_SETCHARFORMAT, SCF_ALL, (LPARAM) &cfmt);\r
/* Why are the following seemingly needed too? */\r
- SendMessage(hText, EM_SETCHARFORMAT, SCF_DEFAULT, (LPARAM) &cfmt); \r
- SendMessage(hInput, EM_SETCHARFORMAT, SCF_DEFAULT, (LPARAM) &cfmt); \r
+ SendMessage(hText, EM_SETCHARFORMAT, SCF_DEFAULT, (LPARAM) &cfmt);\r
+ SendMessage(hInput, EM_SETCHARFORMAT, SCF_DEFAULT, (LPARAM) &cfmt);\r
SendMessage(hText, EM_EXGETSEL, 0, (LPARAM)&sel);\r
tmpsel.cpMin = 0;\r
tmpsel.cpMax = -1; /*999999?*/\r
SendMessage(hText, EM_EXSETSEL, 0, (LPARAM)&tmpsel);\r
- SendMessage(hText, EM_SETCHARFORMAT, SCF_SELECTION, (LPARAM) &cfmt); \r
+ SendMessage(hText, EM_SETCHARFORMAT, SCF_SELECTION, (LPARAM) &cfmt);\r
/* Trying putting this here too. It still seems to tickle a RichEdit\r
* bug: sometimes RichEdit indents the first line of a paragraph too.\r
*/\r
FILE *f;\r
UINT number;\r
char fileTitle[MSG_SIZ];\r
+ char buf[MSG_SIZ];\r
+ static SnapData sd;\r
\r
switch (message) {\r
\r
case WM_MBUTTONUP:\r
case WM_RBUTTONUP:\r
case WM_MOUSEMOVE:\r
+ case WM_MOUSEWHEEL:\r
MouseEvent(hwnd, message, wParam, lParam);\r
break;\r
\r
+ JAWS_KB_NAVIGATION\r
+\r
case WM_CHAR:\r
- \r
- if (appData.icsActive) {\r
- if (wParam == '\t') {\r
- if (GetKeyState(VK_SHIFT) < 0) {\r
- /* shifted */\r
- HWND h = GetDlgItem(hwndConsole, OPT_ConsoleInput);\r
- if (IsIconic(hwndConsole)) ShowWindow(hwndConsole, SW_RESTORE);\r
- SetFocus(h);\r
- } else {\r
- /* unshifted */\r
- HWND h = GetDlgItem(hwndConsole, OPT_ConsoleText);\r
- if (IsIconic(hwndConsole)) ShowWindow(hwndConsole, SW_RESTORE);\r
- SetFocus(h);\r
- }\r
- } else {\r
- HWND h = GetDlgItem(hwndConsole, OPT_ConsoleInput);\r
- if (IsIconic(hwndConsole)) ShowWindow(hwndConsole, SW_RESTORE);\r
- SetFocus(h);\r
- SendMessage(h, message, wParam, lParam);\r
- }\r
- } else if (isalpha((char)wParam) || isdigit((char)wParam)) {\r
- PopUpMoveDialog((char)wParam);\r
+\r
+ JAWS_ALT_INTERCEPT\r
+\r
+ if (appData.icsActive && (char)wParam > ' ' && !((char)wParam >= '1' && (char)wParam <= '9')) {\r
+ // [HGM] movenum: for non-zero digits we always do type-in dialog\r
+ HWND h = GetDlgItem(hwndConsole, OPT_ConsoleInput);\r
+ if (IsIconic(hwndConsole)) ShowWindow(hwndConsole, SW_RESTORE);\r
+ SetFocus(h);\r
+ SendMessage(h, message, wParam, lParam);\r
+ } else if(lParam != KF_REPEAT) {\r
+ if (isalpha((char)wParam) || isdigit((char)wParam)) {\r
+ PopUpMoveDialog((char)wParam);\r
+ } else if((char)wParam == 003) CopyGameToClipboard();\r
+ else if((char)wParam == 026) PasteGameOrFENFromClipboard();\r
}\r
+\r
break;\r
\r
case WM_PALETTECHANGED:\r
SelectPalette(hdc, hPal, TRUE);\r
nnew = RealizePalette(hdc);\r
if (nnew > 0) {\r
- paletteChanged = TRUE;\r
+ paletteChanged = TRUE;\r
#if 0\r
UpdateColors(hdc);\r
#else\r
SelectPalette(hdc, hPal, FALSE);\r
nnew = RealizePalette(hdc);\r
if (nnew > 0) {\r
- InvalidateRect(hwnd, &boardRect, FALSE);\r
+ InvalidateRect(hwnd, &boardRect, FALSE);\r
}\r
ReleaseDC(hwnd, hdc);\r
return TRUE;\r
case IDM_NewGame:\r
ResetGameEvent();\r
AnalysisPopDown();\r
+ SAY("new game enter a move to play against the computer with white");\r
+ break;\r
+\r
+ case IDM_NewGameFRC:\r
+ if( NewGameFRC() == 0 ) {\r
+ ResetGameEvent();\r
+ AnalysisPopDown();\r
+ }\r
+ break;\r
+\r
+ case IDM_NewVariant:\r
+ NewVariantPopup(hwnd);\r
break;\r
\r
case IDM_LoadGame:\r
Reset(FALSE, TRUE);\r
}\r
number = 1;\r
- f = OpenFileDialog(hwnd, FALSE, "",\r
- appData.oldSaveStyle ? "pos" : "fen",\r
- POSITION_FILT,\r
- "Load Position from File", &number, fileTitle, NULL);\r
+ f = OpenFileDialog(hwnd, "rb", "",\r
+ appData.oldSaveStyle ? "pos" : "fen",\r
+ POSITION_FILT,\r
+ "Load Position from File", &number, fileTitle, NULL);\r
if (f != NULL) {\r
- LoadPosition(f, number, fileTitle);\r
+ LoadPosition(f, number, fileTitle);\r
}\r
break;\r
\r
\r
case IDM_SaveGame:\r
defName = DefaultFileName(appData.oldSaveStyle ? "gam" : "pgn");\r
- f = OpenFileDialog(hwnd, TRUE, defName,\r
- appData.oldSaveStyle ? "gam" : "pgn",\r
- GAME_FILT,\r
- "Save Game to File", NULL, fileTitle, NULL);\r
+ f = OpenFileDialog(hwnd, "a", defName,\r
+ appData.oldSaveStyle ? "gam" : "pgn",\r
+ GAME_FILT,\r
+ "Save Game to File", NULL, fileTitle, NULL);\r
if (f != NULL) {\r
- SaveGame(f, 0, "");\r
+ SaveGame(f, 0, "");\r
}\r
break;\r
\r
case IDM_SavePosition:\r
defName = DefaultFileName(appData.oldSaveStyle ? "pos" : "fen");\r
- f = OpenFileDialog(hwnd, TRUE, defName,\r
- appData.oldSaveStyle ? "pos" : "fen",\r
- POSITION_FILT,\r
- "Save Position to File", NULL, fileTitle, NULL);\r
+ f = OpenFileDialog(hwnd, "a", defName,\r
+ appData.oldSaveStyle ? "pos" : "fen",\r
+ POSITION_FILT,\r
+ "Save Position to File", NULL, fileTitle, NULL);\r
+ if (f != NULL) {\r
+ SavePosition(f, 0, "");\r
+ }\r
+ break;\r
+\r
+ case IDM_SaveDiagram:\r
+ defName = "diagram";\r
+ f = OpenFileDialog(hwnd, "wb", defName,\r
+ "bmp",\r
+ DIAGRAM_FILT,\r
+ "Save Diagram to File", NULL, fileTitle, NULL);\r
if (f != NULL) {\r
- SavePosition(f, 0, "");\r
+ SaveDiagram(f);\r
}\r
break;\r
\r
PasteGameFromClipboard();\r
break;\r
\r
+ case IDM_CopyGameListToClipboard:\r
+ CopyGameListToClipboard();\r
+ break;\r
+\r
+ /* [AS] Autodetect FEN or PGN data */\r
+ case IDM_PasteAny:\r
+ PasteGameOrFENFromClipboard();\r
+ break;\r
+\r
+ /* [AS] Move history */\r
+ case IDM_ShowMoveHistory:\r
+ if( MoveHistoryIsUp() ) {\r
+ MoveHistoryPopDown();\r
+ }\r
+ else {\r
+ MoveHistoryPopUp();\r
+ }\r
+ break;\r
+\r
+ /* [AS] Eval graph */\r
+ case IDM_ShowEvalGraph:\r
+ if( EvalGraphIsUp() ) {\r
+ EvalGraphPopDown();\r
+ }\r
+ else {\r
+ EvalGraphPopUp();\r
+ SetFocus(hwndMain);\r
+ }\r
+ break;\r
+\r
+ /* [AS] Engine output */\r
+ case IDM_ShowEngineOutput:\r
+ if( EngineOutputIsUp() ) {\r
+ EngineOutputPopDown();\r
+ }\r
+ else {\r
+ EngineOutputPopUp();\r
+ }\r
+ break;\r
+\r
+ /* [AS] User adjudication */\r
+ case IDM_UserAdjudication_White:\r
+ UserAdjudicationEvent( +1 );\r
+ break;\r
+\r
+ case IDM_UserAdjudication_Black:\r
+ UserAdjudicationEvent( -1 );\r
+ break;\r
+\r
+ case IDM_UserAdjudication_Draw:\r
+ UserAdjudicationEvent( 0 );\r
+ break;\r
+\r
+ /* [AS] Game list options dialog */\r
+ case IDM_GameListOptions:\r
+ GameListOptions();\r
+ break;\r
+\r
+ case IDM_NewChat:\r
+ ChatPopUp();\r
+ break;\r
+\r
case IDM_CopyPosition:\r
CopyFENToClipboard();\r
break;\r
* refresh the tags dialog only if it's visible\r
*/\r
if (gameMode == MachinePlaysWhite && IsWindowVisible(editTagsDialog)) {\r
- char *tags;\r
- tags = PGNTags(&gameInfo);\r
- TagsPopUp(tags, CmailMsg());\r
- free(tags);\r
+ char *tags;\r
+ tags = PGNTags(&gameInfo);\r
+ TagsPopUp(tags, CmailMsg());\r
+ free(tags);\r
}\r
+ SAY("computer starts playing white");\r
break;\r
\r
case IDM_MachineBlack:\r
* refresh the tags dialog only if it's visible\r
*/\r
if (gameMode == MachinePlaysBlack && IsWindowVisible(editTagsDialog)) {\r
- char *tags;\r
- tags = PGNTags(&gameInfo);\r
- TagsPopUp(tags, CmailMsg());\r
- free(tags);\r
+ char *tags;\r
+ tags = PGNTags(&gameInfo);\r
+ TagsPopUp(tags, CmailMsg());\r
+ free(tags);\r
}\r
+ SAY("computer starts playing black");\r
break;\r
\r
case IDM_TwoMachines:\r
* refresh the tags dialog only if it's visible\r
*/\r
if (gameMode == TwoMachinesPlay && IsWindowVisible(editTagsDialog)) {\r
- char *tags;\r
- tags = PGNTags(&gameInfo);\r
- TagsPopUp(tags, CmailMsg());\r
- free(tags);\r
+ char *tags;\r
+ tags = PGNTags(&gameInfo);\r
+ TagsPopUp(tags, CmailMsg());\r
+ free(tags);\r
}\r
+ SAY("programs start playing each other");\r
break;\r
\r
case IDM_AnalysisMode:\r
if (!first.analysisSupport) {\r
- char buf[MSG_SIZ];\r
sprintf(buf, "%s does not support analysis", first.tidy);\r
DisplayError(buf, 0);\r
} else {\r
- if (!appData.showThinking) ToggleShowThinking();\r
- AnalyzeModeEvent();\r
+ SAY("analyzing current position");\r
+ /* [DM] icsEngineAnlyze [HGM] Why is this front-end??? */\r
+ if (appData.icsActive) {\r
+ if (gameMode != IcsObserving) {\r
+ sprintf(buf, "You are not observing a game");\r
+ DisplayError(buf, 0);\r
+ /* secure check */\r
+ if (appData.icsEngineAnalyze) {\r
+ if (appData.debugMode)\r
+ fprintf(debugFP, "Found unexpected active ICS engine analyze \n");\r
+ ExitAnalyzeMode();\r
+ ModeHighlight();\r
+ break;\r
+ }\r
+ break;\r
+ } else {\r
+ /* if enable, user want disable icsEngineAnalyze */\r
+ if (appData.icsEngineAnalyze) {\r
+ ExitAnalyzeMode();\r
+ ModeHighlight();\r
+ break;\r
+ }\r
+ appData.icsEngineAnalyze = TRUE;\r
+ if (appData.debugMode) fprintf(debugFP, "ICS engine analyze starting...\n");\r
+ }\r
+ }\r
+ if (!appData.showThinking) ToggleShowThinking();\r
+ AnalyzeModeEvent();\r
}\r
break;\r
\r
sprintf(buf, "%s does not support analysis", first.tidy);\r
DisplayError(buf, 0);\r
} else {\r
- if (!appData.showThinking) ToggleShowThinking();\r
- AnalyzeFileEvent();\r
- LoadGameDialog(hwnd, "Analyze Game from File");\r
- AnalysisPeriodicEvent(1);\r
+ if (!appData.showThinking) ToggleShowThinking();\r
+ AnalyzeFileEvent();\r
+ LoadGameDialog(hwnd, "Analyze Game from File");\r
+ AnalysisPeriodicEvent(1);\r
}\r
break;\r
\r
\r
case IDM_EditGame:\r
EditGameEvent();\r
+ SAY("edit game");\r
break;\r
\r
case IDM_EditPosition:\r
EditPositionEvent();\r
+ SAY("to set up a position type a FEN");\r
break;\r
\r
case IDM_Training:\r
\r
case IDM_EditComment:\r
if (commentDialogUp && editComment) {\r
- CommentPopDown();\r
+ CommentPopDown();\r
} else {\r
- EditCommentEvent();\r
+ EditCommentEvent();\r
}\r
break;\r
\r
PopUpMoveDialog('\000');\r
break;\r
\r
+ case IDM_TypeInName:\r
+ PopUpNameDialog('\000');\r
+ break;\r
+\r
case IDM_Backward:\r
BackwardEvent();\r
SetFocus(hwndMain);\r
break;\r
\r
+ JAWS_MENU_ITEMS\r
+\r
case IDM_Forward:\r
ForwardEvent();\r
SetFocus(hwndMain);\r
DrawPosition(FALSE, NULL);\r
break;\r
\r
+ case IDM_FlipClock:\r
+ flipClock = !flipClock;\r
+ DisplayBothClocks();\r
+ DrawPosition(FALSE, NULL);\r
+ break;\r
+\r
+ case IDM_MuteSounds:\r
+ mute = !mute; // [HGM] mute: keep track of global muting variable\r
+ CheckMenuItem(GetMenu(hwndMain),IDM_MuteSounds,\r
+ MF_BYCOMMAND|(mute?MF_CHECKED:MF_UNCHECKED));\r
+ break;\r
+\r
case IDM_GeneralOptions:\r
GeneralOptionsPopup(hwnd);\r
+ DrawPosition(TRUE, NULL);\r
break;\r
\r
case IDM_BoardOptions:\r
BoardOptionsPopup(hwnd);\r
break;\r
\r
+ case IDM_EnginePlayOptions:\r
+ EnginePlayOptionsPopup(hwnd);\r
+ break;\r
+\r
+ case IDM_Engine1Options:\r
+ EngineOptionsPopup(hwnd, &first);\r
+ break;\r
+\r
+ case IDM_Engine2Options:\r
+ EngineOptionsPopup(hwnd, &second);\r
+ break;\r
+\r
+ case IDM_OptionsUCI:\r
+ UciOptionsPopup(hwnd);\r
+ break;\r
+\r
case IDM_IcsOptions:\r
IcsOptionsPopup(hwnd);\r
break;\r
case IDM_SaveSettingsOnExit:\r
saveSettingsOnExit = !saveSettingsOnExit;\r
(void) CheckMenuItem(GetMenu(hwndMain), IDM_SaveSettingsOnExit,\r
- MF_BYCOMMAND|(saveSettingsOnExit ?\r
- MF_CHECKED : MF_UNCHECKED));\r
+ MF_BYCOMMAND|(saveSettingsOnExit ?\r
+ MF_CHECKED : MF_UNCHECKED));\r
break;\r
\r
case IDM_Hint:\r
case IDM_Debug:\r
appData.debugMode = !appData.debugMode;\r
if (appData.debugMode) {\r
- char dir[MSG_SIZ];\r
- GetCurrentDirectory(MSG_SIZ, dir);\r
- SetCurrentDirectory(installDir);\r
- debugFP = fopen("WinBoard.debug", "w");\r
+ char dir[MSG_SIZ];\r
+ GetCurrentDirectory(MSG_SIZ, dir);\r
+ SetCurrentDirectory(installDir);\r
+ debugFP = fopen(appData.nameOfDebugFile, "w");\r
SetCurrentDirectory(dir);\r
setbuf(debugFP, NULL);\r
} else {\r
- fclose(debugFP);\r
+ fclose(debugFP);\r
debugFP = NULL;\r
}\r
break;\r
\r
case IDM_HELPCONTENTS:\r
- if (!WinHelp (hwnd, "winboard.hlp", HELP_KEY,(DWORD)(LPSTR)"CONTENTS")) {\r
- MessageBox (GetFocus(),\r
- "Unable to activate help",\r
- szAppName, MB_SYSTEMMODAL|MB_OK|MB_ICONHAND);\r
+ if (!MyHelp (hwnd, "winboard.hlp", HELP_KEY,(DWORD)(LPSTR)"CONTENTS") &&\r
+ !HtmlHelp(hwnd, "winboard.chm", 0, 0) ) {\r
+ MessageBox (GetFocus(),\r
+ "Unable to activate help",\r
+ szAppName, MB_SYSTEMMODAL|MB_OK|MB_ICONHAND);\r
}\r
break;\r
\r
case IDM_HELPSEARCH:\r
- if (!WinHelp(hwnd, "winboard.hlp", HELP_PARTIALKEY, (DWORD)(LPSTR)"")) {\r
- MessageBox (GetFocus(),\r
- "Unable to activate help",\r
- szAppName, MB_SYSTEMMODAL|MB_OK|MB_ICONHAND);\r
+ if (!MyHelp (hwnd, "winboard.hlp", HELP_PARTIALKEY, (DWORD)(LPSTR)"") &&\r
+ !HtmlHelp(hwnd, "winboard.chm", 0, 0) ) {\r
+ MessageBox (GetFocus(),\r
+ "Unable to activate help",\r
+ szAppName, MB_SYSTEMMODAL|MB_OK|MB_ICONHAND);\r
}\r
break;\r
\r
case IDM_HELPHELP:\r
if(!WinHelp(hwnd, (LPSTR)NULL, HELP_HELPONHELP, 0)) {\r
- MessageBox (GetFocus(),\r
- "Unable to activate help",\r
- szAppName, MB_SYSTEMMODAL|MB_OK|MB_ICONHAND);\r
+ MessageBox (GetFocus(),\r
+ "Unable to activate help",\r
+ szAppName, MB_SYSTEMMODAL|MB_OK|MB_ICONHAND);\r
}\r
break;\r
\r
case IDM_ABOUT:\r
lpProc = MakeProcInstance((FARPROC)About, hInst);\r
- DialogBox(hInst, \r
- (gameInfo.event && strcmp(gameInfo.event, "Easter Egg Hunt") == 0) ?\r
- "AboutBox2" : "AboutBox", hwnd, (DLGPROC)lpProc);\r
+ DialogBox(hInst,\r
+ (gameInfo.event && strcmp(gameInfo.event, "Easter Egg Hunt") == 0) ?\r
+ "AboutBox2" : "AboutBox", hwnd, (DLGPROC)lpProc);\r
FreeProcInstance(lpProc);\r
break;\r
\r
case IDM_DirectCommand1:\r
AskQuestionEvent("Direct Command",\r
- "Send to chess program:", "", "1");\r
+ "Send to chess program:", "", "1");\r
break;\r
case IDM_DirectCommand2:\r
AskQuestionEvent("Direct Command",\r
- "Send to second chess program:", "", "2");\r
+ "Send to second chess program:", "", "2");\r
break;\r
\r
case EP_WhitePawn:\r
fromX = fromY = -1;\r
break;\r
\r
+ case EP_WhiteFerz:\r
+ EditPositionMenuEvent(WhiteFerz, fromX, fromY);\r
+ fromX = fromY = -1;\r
+ break;\r
+\r
+ case EP_WhiteWazir:\r
+ EditPositionMenuEvent(WhiteWazir, fromX, fromY);\r
+ fromX = fromY = -1;\r
+ break;\r
+\r
+ case EP_WhiteAlfil:\r
+ EditPositionMenuEvent(WhiteAlfil, fromX, fromY);\r
+ fromX = fromY = -1;\r
+ break;\r
+\r
+ case EP_WhiteCannon:\r
+ EditPositionMenuEvent(WhiteCannon, fromX, fromY);\r
+ fromX = fromY = -1;\r
+ break;\r
+\r
+ case EP_WhiteCardinal:\r
+ EditPositionMenuEvent(WhiteAngel, fromX, fromY);\r
+ fromX = fromY = -1;\r
+ break;\r
+\r
+ case EP_WhiteMarshall:\r
+ EditPositionMenuEvent(WhiteMarshall, fromX, fromY);\r
+ fromX = fromY = -1;\r
+ break;\r
+\r
case EP_WhiteKing:\r
EditPositionMenuEvent(WhiteKing, fromX, fromY);\r
fromX = fromY = -1;\r
fromX = fromY = -1;\r
break;\r
\r
+ case EP_BlackFerz:\r
+ EditPositionMenuEvent(BlackFerz, fromX, fromY);\r
+ fromX = fromY = -1;\r
+ break;\r
+\r
+ case EP_BlackWazir:\r
+ EditPositionMenuEvent(BlackWazir, fromX, fromY);\r
+ fromX = fromY = -1;\r
+ break;\r
+\r
+ case EP_BlackAlfil:\r
+ EditPositionMenuEvent(BlackAlfil, fromX, fromY);\r
+ fromX = fromY = -1;\r
+ break;\r
+\r
+ case EP_BlackCannon:\r
+ EditPositionMenuEvent(BlackCannon, fromX, fromY);\r
+ fromX = fromY = -1;\r
+ break;\r
+\r
+ case EP_BlackCardinal:\r
+ EditPositionMenuEvent(BlackAngel, fromX, fromY);\r
+ fromX = fromY = -1;\r
+ break;\r
+\r
+ case EP_BlackMarshall:\r
+ EditPositionMenuEvent(BlackMarshall, fromX, fromY);\r
+ fromX = fromY = -1;\r
+ break;\r
+\r
case EP_BlackKing:\r
EditPositionMenuEvent(BlackKing, fromX, fromY);\r
fromX = fromY = -1;\r
fromX = fromY = -1;\r
break;\r
\r
+ case EP_Promote:\r
+ EditPositionMenuEvent(PromotePiece, fromX, fromY);\r
+ fromX = fromY = -1;\r
+ break;\r
+\r
+ case EP_Demote:\r
+ EditPositionMenuEvent(DemotePiece, fromX, fromY);\r
+ fromX = fromY = -1;\r
+ break;\r
+\r
case DP_Pawn:\r
DropMenuEvent(WhitePawn, fromX, fromY);\r
fromX = fromY = -1;\r
AutoPlayGameLoop(); /* call into back end */\r
break;\r
case ANALYSIS_TIMER_ID:\r
- if ((gameMode == AnalyzeMode || gameMode == AnalyzeFile) && \r
- appData.periodicUpdates) {\r
- AnalysisPeriodicEvent(0);\r
+ if ((gameMode == AnalyzeMode || gameMode == AnalyzeFile\r
+ || appData.icsEngineAnalyze) && appData.periodicUpdates) {\r
+ AnalysisPeriodicEvent(0);\r
} else {\r
- KillTimer(hwnd, analysisTimerEvent);\r
- analysisTimerEvent = 0;\r
+ KillTimer(hwnd, analysisTimerEvent);\r
+ analysisTimerEvent = 0;\r
}\r
break;\r
case DELAYED_TIMER_ID:\r
InputEvent(hwnd, message, wParam, lParam);\r
break;\r
\r
+ /* [AS] Also move "attached" child windows */\r
+ case WM_WINDOWPOSCHANGING:\r
+\r
+ if( hwnd == hwndMain && appData.useStickyWindows ) {\r
+ LPWINDOWPOS lpwp = (LPWINDOWPOS) lParam;\r
+\r
+ if( ((lpwp->flags & SWP_NOMOVE) == 0) && ((lpwp->flags & SWP_NOSIZE) != 0) ) {\r
+ /* Window is moving */\r
+ RECT rcMain;\r
+\r
+// GetWindowRect( hwnd, &rcMain ); //[HGM] sticky: in XP this returned new position, not old\r
+ rcMain.left = boardX; // replace by these 4 lines to reconstruct old rect\r
+ rcMain.right = boardX + winWidth;\r
+ rcMain.top = boardY;\r
+ rcMain.bottom = boardY + winHeight;\r
+\r
+ ReattachAfterMove( &rcMain, lpwp->x, lpwp->y, moveHistoryDialog, &wpMoveHistory );\r
+ ReattachAfterMove( &rcMain, lpwp->x, lpwp->y, evalGraphDialog, &wpEvalGraph );\r
+ ReattachAfterMove( &rcMain, lpwp->x, lpwp->y, engineOutputDialog, &wpEngineOutput );\r
+ ReattachAfterMove( &rcMain, lpwp->x, lpwp->y, gameListDialog, &wpGameList );\r
+ ReattachAfterMove( &rcMain, lpwp->x, lpwp->y, hwndConsole, &wpConsole );\r
+ boardX = lpwp->x;\r
+ boardY = lpwp->y;\r
+ }\r
+ }\r
+ break;\r
+\r
+ /* [AS] Snapping */\r
case WM_ENTERSIZEMOVE:\r
+ if(appData.debugMode) { fprintf(debugFP, "size-move\n"); }\r
if (hwnd == hwndMain) {\r
doingSizing = TRUE;\r
lastSizing = 0;\r
}\r
+ return OnEnterSizeMove( &sd, hwnd, wParam, lParam );\r
break;\r
\r
case WM_SIZING:\r
+ if(appData.debugMode) { fprintf(debugFP, "sizing\n"); }\r
if (hwnd == hwndMain) {\r
lastSizing = wParam;\r
}\r
break;\r
\r
+ case WM_MOVING:\r
+ if(appData.debugMode) { fprintf(debugFP, "moving\n"); }\r
+ return OnMoving( &sd, hwnd, wParam, lParam );\r
+\r
case WM_EXITSIZEMOVE:\r
+ if(appData.debugMode) { fprintf(debugFP, "exit size-move, size = %d\n", squareSize); }\r
if (hwnd == hwndMain) {\r
RECT client;\r
doingSizing = FALSE;\r
GetClientRect(hwnd, &client);\r
ResizeBoard(client.right, client.bottom, lastSizing);\r
lastSizing = 0;\r
+ if(appData.debugMode) { fprintf(debugFP, "square size = %d\n", squareSize); }\r
}\r
+ return OnExitSizeMove( &sd, hwnd, wParam, lParam );\r
break;\r
\r
case WM_DESTROY: /* message: window being destroyed */\r
}\r
break;\r
\r
- default: /* Passes it on if unprocessed */\r
+ default: /* Passes it on if unprocessed */\r
return (DefWindowProc(hwnd, message, wParam, lParam));\r
}\r
return 0;\r
}\r
\r
\r
-/* \r
- * returns TRUE if user selects a different color, FALSE otherwise \r
+/*\r
+ * returns TRUE if user selects a different color, FALSE otherwise\r
*/\r
\r
BOOL\r
MyPlaySound(MySound *ms)\r
{\r
BOOLEAN ok = FALSE;\r
+\r
+ if(mute) return TRUE; // [HGM] mute: suppress all sound play when muted\r
switch (ms->name[0]) {\r
case NULLCHAR:\r
+ if(appData.debugMode) fprintf(debugFP, "silence\n");\r
/* Silence */\r
ok = TRUE;\r
break;\r
ok = PlaySound(ms->name + 1, NULL, SND_ALIAS|SND_ASYNC);\r
}\r
if (!ok) ok = MessageBeep(MB_OK);\r
- break; \r
+ break;\r
case '!':\r
/* Builtin wave resource, or "!" alone for silence */\r
if (ms->name[1]) {\r
\r
\r
FILE *\r
-OpenFileDialog(HWND hwnd, BOOL write, char *defName, char *defExt,\r
- char *nameFilt, char *dlgTitle, UINT *number,\r
- char fileTitle[MSG_SIZ], char fileName[MSG_SIZ])\r
+OpenFileDialog(HWND hwnd, char *write, char *defName, char *defExt, // [HGM] diag: type of 'write' now string\r
+ char *nameFilt, char *dlgTitle, UINT *number,\r
+ char fileTitle[MSG_SIZ], char fileName[MSG_SIZ])\r
{\r
OPENFILENAME openFileName;\r
char buf1[MSG_SIZ];\r
openFileName.nMaxFileTitle = fileTitle ? MSG_SIZ : 0;\r
openFileName.lpstrInitialDir = NULL;\r
openFileName.lpstrTitle = dlgTitle;\r
- openFileName.Flags = OFN_PATHMUSTEXIST | OFN_HIDEREADONLY \r
- | (write ? 0 : OFN_FILEMUSTEXIST) \r
+ openFileName.Flags = OFN_PATHMUSTEXIST | OFN_HIDEREADONLY\r
+ | (write[0] != 'r' ? 0 : OFN_FILEMUSTEXIST)\r
| (number ? OFN_ENABLETEMPLATE | OFN_ENABLEHOOK: 0)\r
| (oldDialog ? 0 : OFN_EXPLORER);\r
openFileName.nFileOffset = 0;\r
(LPOFNHOOKPROC) OldOpenFileHook : (LPOFNHOOKPROC) OpenFileHook;\r
openFileName.lpTemplateName = (LPSTR)(oldDialog ? 1536 : DLG_IndexNumber);\r
\r
- if (write ? GetSaveFileName(&openFileName) : \r
- GetOpenFileName(&openFileName)) {\r
+ if (write[0] != 'r' ? GetSaveFileName(&openFileName) :\r
+ GetOpenFileName(&openFileName)) {\r
/* open the file */\r
- f = fopen(openFileName.lpstrFile, write ? "a" : "rb");\r
+ f = fopen(openFileName.lpstrFile, write);\r
if (f == NULL) {\r
MessageBox(hwnd, "File open failed", NULL,\r
- MB_OK|MB_ICONEXCLAMATION);\r
+ MB_OK|MB_ICONEXCLAMATION);\r
return NULL;\r
}\r
} else {\r
VOID APIENTRY\r
MenuPopup(HWND hwnd, POINT pt, HMENU hmenu, UINT def)\r
{\r
- HMENU hmenuTrackPopup; /* floating pop-up menu */\r
+ HMENU hmenuTrackPopup; /* floating pop-up menu */\r
\r
/*\r
* Get the first pop-up menu in the menu template. This is the\r
\r
/* Draw and track the floating pop-up menu. */\r
TrackPopupMenu(hmenuTrackPopup, TPM_CENTERALIGN | TPM_RIGHTBUTTON,\r
- pt.x, pt.y, 0, hwnd, NULL);\r
+ pt.x, pt.y, 0, hwnd, NULL);\r
\r
/* Destroy the menu.*/\r
DestroyMenu(hmenu);\r
}\r
- \r
+\r
typedef struct {\r
HWND hDlg, hText;\r
int sizeX, sizeY, newSizeX, newSizeY;\r
pt.x = rect.left + (cl->newSizeX - cl->sizeX)/2;\r
pt.y = rect.top + cl->newSizeY - cl->sizeY;\r
ScreenToClient(cl->hDlg, &pt);\r
- cl->hdwp = DeferWindowPos(cl->hdwp, hChild, NULL, \r
+ cl->hdwp = DeferWindowPos(cl->hdwp, hChild, NULL,\r
pt.x, pt.y, rect.right - rect.left, rect.bottom - rect.top, SWP_NOZORDER);\r
return TRUE;\r
}\r
RECT rectText;\r
int newTextHeight, newTextWidth;\r
ResizeEditPlusButtonsClosure cl;\r
- \r
+\r
/*if (IsIconic(hDlg)) return;*/\r
if (newSizeX == sizeX && newSizeY == sizeY) return;\r
- \r
+\r
cl.hdwp = BeginDeferWindowPos(8);\r
\r
GetWindowRect(hText, &rectText); /* gives screen coords */\r
newSizeY += -newTextHeight;\r
newTextHeight = 0;\r
}\r
- cl.hdwp = DeferWindowPos(cl.hdwp, hText, NULL, 0, 0, \r
+ cl.hdwp = DeferWindowPos(cl.hdwp, hText, NULL, 0, 0,\r
newTextWidth, newTextHeight, SWP_NOZORDER|SWP_NOMOVE);\r
\r
cl.hDlg = hDlg;\r
EndDeferWindowPos(cl.hdwp);\r
}\r
\r
-/* Center one window over another */\r
-BOOL CenterWindow (HWND hwndChild, HWND hwndParent)\r
+BOOL CenterWindowEx(HWND hwndChild, HWND hwndParent, int mode)\r
{\r
RECT rChild, rParent;\r
int wChild, hChild, wParent, hParent;\r
/* Calculate new X position, then adjust for screen */\r
xNew = rParent.left + ((wParent - wChild) /2);\r
if (xNew < 0) {\r
- xNew = 0;\r
+ xNew = 0;\r
} else if ((xNew+wChild) > wScreen) {\r
- xNew = wScreen - wChild;\r
+ xNew = wScreen - wChild;\r
}\r
\r
/* Calculate new Y position, then adjust for screen */\r
- yNew = rParent.top + ((hParent - hChild) /2);\r
+ if( mode == 0 ) {\r
+ yNew = rParent.top + ((hParent - hChild) /2);\r
+ }\r
+ else {\r
+ yNew = rParent.top + GetSystemMetrics( SM_CYCAPTION ) * 2 / 3;\r
+ }\r
+\r
if (yNew < 0) {\r
- yNew = 0;\r
+ yNew = 0;\r
} else if ((yNew+hChild) > hScreen) {\r
- yNew = hScreen - hChild;\r
+ yNew = hScreen - hChild;\r
}\r
\r
/* Set it, and return */\r
return SetWindowPos (hwndChild, NULL,\r
- xNew, yNew, 0, 0, SWP_NOSIZE | SWP_NOZORDER);\r
+ xNew, yNew, 0, 0, SWP_NOSIZE | SWP_NOZORDER);\r
+}\r
+\r
+/* Center one window over another */\r
+BOOL CenterWindow (HWND hwndChild, HWND hwndParent)\r
+{\r
+ return CenterWindowEx( hwndChild, hwndParent, 0 );\r
}\r
\r
/*---------------------------------------------------------------------------*\\r
{\r
EnableWindow(GetDlgItem(hDlg, OPT_ChessEngineName),\r
IsDlgButtonChecked(hDlg, OPT_ChessEngine) ||\r
- appData.zippyPlay && IsDlgButtonChecked(hDlg, OPT_ChessServer));\r
+ (appData.zippyPlay && IsDlgButtonChecked(hDlg, OPT_ChessServer)));\r
EnableWindow(GetDlgItem(hDlg, OPT_SecondChessEngineName),\r
IsDlgButtonChecked(hDlg, OPT_ChessEngine));\r
EnableWindow(GetDlgItem(hDlg, OPT_ChessServerName),\r
CenterWindow (hDlg, GetDesktopWindow());\r
/* Initialize the dialog items */\r
InitEngineBox(hDlg, GetDlgItem(hDlg, OPT_ChessEngineName),\r
- appData.firstChessProgram, "fd", appData.firstDirectory,\r
- firstChessProgramNames);\r
+ appData.firstChessProgram, "fd", appData.firstDirectory,\r
+ firstChessProgramNames);\r
InitEngineBox(hDlg, GetDlgItem(hDlg, OPT_SecondChessEngineName),\r
- appData.secondChessProgram, "sd", appData.secondDirectory,\r
- secondChessProgramNames);\r
+ appData.secondChessProgram, "sd", appData.secondDirectory,\r
+ secondChessProgramNames);\r
hwndCombo = GetDlgItem(hDlg, OPT_ChessServerName);\r
- InitComboStringsFromOption(hwndCombo, icsNames); \r
+ InitComboStringsFromOption(hwndCombo, icsNames);\r
sprintf(buf, "%s /icsport=%s", appData.icsHost, appData.icsPort);\r
if (*appData.icsHelper != NULLCHAR) {\r
char *q = QuoteForFilename(appData.icsHelper);\r
SendMessage(hwndCombo, CB_SETCURSEL, (WPARAM) -1, (LPARAM) 0);\r
SendMessage(hwndCombo, WM_SETTEXT, (WPARAM) 0, (LPARAM) buf);\r
}\r
- if (chessProgram) {\r
- CheckDlgButton(hDlg, OPT_ChessEngine, BST_CHECKED);\r
- } else if (appData.icsActive) {\r
+\r
+ if (appData.icsActive) {\r
CheckDlgButton(hDlg, OPT_ChessServer, BST_CHECKED);\r
- } else if (appData.noChessProgram) {\r
+ }\r
+ else if (appData.noChessProgram) {\r
CheckDlgButton(hDlg, OPT_View, BST_CHECKED);\r
}\r
+ else {\r
+ CheckDlgButton(hDlg, OPT_ChessEngine, BST_CHECKED);\r
+ }\r
+\r
SetStartupDialogEnables(hDlg);\r
return TRUE;\r
\r
case IDOK:\r
if (IsDlgButtonChecked(hDlg, OPT_ChessEngine)) {\r
strcpy(buf, "/fcp=");\r
- GetDlgItemText(hDlg, OPT_ChessEngineName, buf + strlen(buf), sizeof(buf) - strlen(buf));\r
+ GetDlgItemText(hDlg, OPT_ChessEngineName, buf + strlen(buf), sizeof(buf) - strlen(buf));\r
p = buf;\r
- ParseArgs(StringGet, &p);\r
+ ParseArgs(StringGet, &p);\r
strcpy(buf, "/scp=");\r
- GetDlgItemText(hDlg, OPT_SecondChessEngineName, buf + strlen(buf), sizeof(buf) - strlen(buf));\r
+ GetDlgItemText(hDlg, OPT_SecondChessEngineName, buf + strlen(buf), sizeof(buf) - strlen(buf));\r
p = buf;\r
- ParseArgs(StringGet, &p);\r
- appData.noChessProgram = FALSE;\r
- appData.icsActive = FALSE;\r
+ ParseArgs(StringGet, &p);\r
+ appData.noChessProgram = FALSE;\r
+ appData.icsActive = FALSE;\r
} else if (IsDlgButtonChecked(hDlg, OPT_ChessServer)) {\r
strcpy(buf, "/ics /icshost=");\r
- GetDlgItemText(hDlg, OPT_ChessServerName, buf + strlen(buf), sizeof(buf) - strlen(buf));\r
+ GetDlgItemText(hDlg, OPT_ChessServerName, buf + strlen(buf), sizeof(buf) - strlen(buf));\r
p = buf;\r
- ParseArgs(StringGet, &p);\r
- if (appData.zippyPlay) {\r
- strcpy(buf, "/fcp=");\r
- GetDlgItemText(hDlg, OPT_ChessEngineName, buf + strlen(buf), sizeof(buf) - strlen(buf));\r
- p = buf;\r
- ParseArgs(StringGet, &p);\r
- }\r
+ ParseArgs(StringGet, &p);\r
+ if (appData.zippyPlay) {\r
+ strcpy(buf, "/fcp=");\r
+ GetDlgItemText(hDlg, OPT_ChessEngineName, buf + strlen(buf), sizeof(buf) - strlen(buf));\r
+ p = buf;\r
+ ParseArgs(StringGet, &p);\r
+ }\r
} else if (IsDlgButtonChecked(hDlg, OPT_View)) {\r
- appData.noChessProgram = TRUE;\r
- appData.icsActive = FALSE;\r
+ appData.noChessProgram = TRUE;\r
+ appData.icsActive = FALSE;\r
} else {\r
- MessageBox(hDlg, "Choose an option, or cancel to exit",\r
- "Option Error", MB_OK|MB_ICONEXCLAMATION);\r
- return TRUE;\r
+ MessageBox(hDlg, "Choose an option, or cancel to exit",\r
+ "Option Error", MB_OK|MB_ICONEXCLAMATION);\r
+ return TRUE;\r
}\r
if (IsDlgButtonChecked(hDlg, OPT_AnyAdditional)) {\r
- GetDlgItemText(hDlg, OPT_AdditionalOptions, buf, sizeof(buf));\r
- p = buf;\r
- ParseArgs(StringGet, &p);\r
+ GetDlgItemText(hDlg, OPT_AdditionalOptions, buf, sizeof(buf));\r
+ p = buf;\r
+ ParseArgs(StringGet, &p);\r
}\r
EndDialog(hDlg, TRUE);\r
return TRUE;\r
\r
case IDM_HELPCONTENTS:\r
if (!WinHelp (hDlg, "winboard.hlp", HELP_KEY,(DWORD)(LPSTR)"CONTENTS")) {\r
- MessageBox (GetFocus(),\r
- "Unable to activate help",\r
- szAppName, MB_SYSTEMMODAL|MB_OK|MB_ICONHAND);\r
+ MessageBox (GetFocus(),\r
+ "Unable to activate help",\r
+ szAppName, MB_SYSTEMMODAL|MB_OK|MB_ICONHAND);\r
}\r
break;\r
\r
/* Center the dialog over the application window */\r
CenterWindow (hDlg, GetWindow (hDlg, GW_OWNER));\r
SetDlgItemText(hDlg, ABOUTBOX_Version, programVersion);\r
+ JAWS_COPYRIGHT\r
return (TRUE);\r
\r
case WM_COMMAND: /* message: received a command */\r
if (LOWORD(wParam) == IDOK /* "OK" box selected? */\r
- || LOWORD(wParam) == IDCANCEL) { /* System menu close command? */\r
+ || LOWORD(wParam) == IDCANCEL) { /* System menu close command? */\r
EndDialog(hDlg, TRUE); /* Exit the dialog */\r
return (TRUE);\r
}\r
SetFocus(GetDlgItem(hDlg, IDOK));\r
}\r
SendMessage(GetDlgItem(hDlg, OPT_CommentText),\r
- WM_SETFONT, (WPARAM)font[boardSize][COMMENT_FONT]->hf,\r
- MAKELPARAM(FALSE, 0));\r
+ WM_SETFONT, (WPARAM)font[boardSize][COMMENT_FONT]->hf,\r
+ MAKELPARAM(FALSE, 0));\r
/* Size and position the dialog */\r
if (!commentDialog) {\r
commentDialog = hDlg;\r
sizeX = rect.right;\r
sizeY = rect.bottom;\r
if (commentX != CW_USEDEFAULT && commentY != CW_USEDEFAULT &&\r
- commentW != CW_USEDEFAULT && commentH != CW_USEDEFAULT) {\r
- WINDOWPLACEMENT wp;\r
- EnsureOnScreen(&commentX, &commentY);\r
- wp.length = sizeof(WINDOWPLACEMENT);\r
- wp.flags = 0;\r
- wp.showCmd = SW_SHOW;\r
- wp.ptMaxPosition.x = wp.ptMaxPosition.y = 0;\r
- wp.rcNormalPosition.left = commentX;\r
- wp.rcNormalPosition.right = commentX + commentW;\r
- wp.rcNormalPosition.top = commentY;\r
- wp.rcNormalPosition.bottom = commentY + commentH;\r
- SetWindowPlacement(hDlg, &wp);\r
-\r
- GetClientRect(hDlg, &rect);\r
- newSizeX = rect.right;\r
- newSizeY = rect.bottom;\r
+ commentW != CW_USEDEFAULT && commentH != CW_USEDEFAULT) {\r
+ WINDOWPLACEMENT wp;\r
+ EnsureOnScreen(&commentX, &commentY, 0, 0);\r
+ wp.length = sizeof(WINDOWPLACEMENT);\r
+ wp.flags = 0;\r
+ wp.showCmd = SW_SHOW;\r
+ wp.ptMaxPosition.x = wp.ptMaxPosition.y = 0;\r
+ wp.rcNormalPosition.left = commentX;\r
+ wp.rcNormalPosition.right = commentX + commentW;\r
+ wp.rcNormalPosition.top = commentY;\r
+ wp.rcNormalPosition.bottom = commentY + commentH;\r
+ SetWindowPlacement(hDlg, &wp);\r
+\r
+ GetClientRect(hDlg, &rect);\r
+ newSizeX = rect.right;\r
+ newSizeY = rect.bottom;\r
ResizeEditPlusButtons(hDlg, hwndText, sizeX, sizeY,\r
- newSizeX, newSizeY);\r
- sizeX = newSizeX;\r
- sizeY = newSizeY;\r
+ newSizeX, newSizeY);\r
+ sizeX = newSizeX;\r
+ sizeY = newSizeY;\r
}\r
}\r
return FALSE;\r
switch (LOWORD(wParam)) {\r
case IDOK:\r
if (editComment) {\r
- char *p, *q;\r
- /* Read changed options from the dialog box */\r
- hwndText = GetDlgItem(hDlg, OPT_CommentText);\r
- len = GetWindowTextLength(hwndText);\r
- str = (char *) malloc(len + 1);\r
- GetWindowText(hwndText, str, len + 1);\r
- p = q = str;\r
- while (*q) {\r
- if (*q == '\r')\r
- q++;\r
- else\r
- *p++ = *q++;\r
- }\r
- *p = NULLCHAR;\r
- ReplaceComment(commentIndex, str);\r
- free(str);\r
+ char *p, *q;\r
+ /* Read changed options from the dialog box */\r
+ hwndText = GetDlgItem(hDlg, OPT_CommentText);\r
+ len = GetWindowTextLength(hwndText);\r
+ str = (char *) malloc(len + 1);\r
+ GetWindowText(hwndText, str, len + 1);\r
+ p = q = str;\r
+ while (*q) {\r
+ if (*q == '\r')\r
+ q++;\r
+ else\r
+ *p++ = *q++;\r
+ }\r
+ *p = NULLCHAR;\r
+ ReplaceComment(commentIndex, str);\r
+ free(str);\r
}\r
CommentPopDown();\r
return TRUE;\r
} else {\r
lpProc = MakeProcInstance((FARPROC)CommentDialog, hInst);\r
CreateDialog(hInst, MAKEINTRESOURCE(DLG_EditComment),\r
- hwndMain, (DLGPROC)lpProc);\r
+ hwndMain, (DLGPROC)lpProc);\r
FreeProcInstance(lpProc);\r
}\r
commentDialogUp = TRUE;\r
/*---------------------------------------------------------------------------*\\r
*\r
* Type-in move dialog functions\r
- * \r
+ *\r
\*---------------------------------------------------------------------------*/\r
\r
LRESULT CALLBACK\r
case WM_INITDIALOG:\r
move[0] = (char) lParam;\r
move[1] = NULLCHAR;\r
- CenterWindow(hDlg, GetWindow(hDlg, GW_OWNER));\r
+ CenterWindowEx(hDlg, GetWindow(hDlg, GW_OWNER), 1 );\r
hInput = GetDlgItem(hDlg, OPT_Move);\r
SetWindowText(hInput, move);\r
SetFocus(hInput);\r
case WM_COMMAND:\r
switch (LOWORD(wParam)) {\r
case IDOK:\r
- if (gameMode != EditGame && currentMove != forwardMostMove && \r
- gameMode != Training) {\r
- DisplayMoveError("Displayed move is not current");\r
+ GetDlgItemText(hDlg, OPT_Move, move, sizeof(move));\r
+ { int n; Board board;\r
+ // [HGM] FENedit\r
+ if(gameMode == EditPosition && ParseFEN(board, &n, move) ) {\r
+ EditPositionPasteFEN(move);\r
+ EndDialog(hDlg, TRUE);\r
+ return TRUE;\r
+ }\r
+ // [HGM] movenum: allow move number to be typed in any mode\r
+ if(sscanf(move, "%d", &n) == 1 && n != 0 ) {\r
+ currentMove = 2*n-1;\r
+ if(currentMove > forwardMostMove) currentMove = forwardMostMove;\r
+ if(currentMove < backwardMostMove) currentMove = backwardMostMove;\r
+ EndDialog(hDlg, TRUE);\r
+ DrawPosition(TRUE, boards[currentMove]);\r
+ if(currentMove > backwardMostMove) DisplayMove(currentMove - 1);\r
+ else DisplayMessage("", "");\r
+ return TRUE;\r
+ }\r
+ }\r
+ if (gameMode != EditGame && currentMove != forwardMostMove &&\r
+ gameMode != Training) {\r
+ DisplayMoveError("Displayed move is not current");\r
} else {\r
- GetDlgItemText(hDlg, OPT_Move, move, sizeof(move));\r
- if (ParseOneMove(move, gameMode == EditPosition ? blackPlaysFirst : currentMove, \r
- &moveType, &fromX, &fromY, &toX, &toY, &promoChar)) {\r
- if (gameMode != Training)\r
- forwardMostMove = currentMove;\r
- UserMoveEvent(fromX, fromY, toX, toY, promoChar); \r
- } else {\r
- DisplayMoveError("Could not parse move");\r
- }\r
+// GetDlgItemText(hDlg, OPT_Move, move, sizeof(move)); // moved upstream\r
+ int ok = ParseOneMove(move, gameMode == EditPosition ? blackPlaysFirst : currentMove,\r
+ &moveType, &fromX, &fromY, &toX, &toY, &promoChar);\r
+ if(!ok && move[0] >= 'a') { move[0] += 'A' - 'a'; ok = 2; } // [HGM] try also capitalized\r
+ if (ok==1 || ok && ParseOneMove(move, gameMode == EditPosition ? blackPlaysFirst : currentMove,\r
+ &moveType, &fromX, &fromY, &toX, &toY, &promoChar)) {\r
+ if (gameMode != Training)\r
+ forwardMostMove = currentMove;\r
+ UserMoveEvent(fromX, fromY, toX, toY, promoChar);\r
+ } else {\r
+ DisplayMoveError("Could not parse move");\r
+ }\r
}\r
EndDialog(hDlg, TRUE);\r
return TRUE;\r
PopUpMoveDialog(char firstchar)\r
{\r
FARPROC lpProc;\r
- \r
- if ((gameMode == BeginningOfGame && !appData.icsActive) || \r
+\r
+ if ((gameMode == BeginningOfGame && !appData.icsActive) ||\r
gameMode == MachinePlaysWhite || gameMode == MachinePlaysBlack ||\r
- gameMode == AnalyzeMode || gameMode == EditGame || \r
- gameMode == EditPosition || gameMode == IcsExamining ||\r
- gameMode == IcsPlayingWhite || gameMode == IcsPlayingBlack ||\r
- gameMode == Training) {\r
+ gameMode == AnalyzeMode || gameMode == EditGame ||\r
+ gameMode == EditPosition || gameMode == IcsExamining ||\r
+ gameMode == IcsPlayingWhite || gameMode == IcsPlayingBlack ||\r
+ isdigit(firstchar) && // [HGM] movenum: allow typing in of move nr in 'passive' modes\r
+ ( gameMode == AnalyzeFile || gameMode == PlayFromGameFile ||\r
+ gameMode == IcsObserving || gameMode == TwoMachinesPlay ) ||\r
+ gameMode == Training) {\r
lpProc = MakeProcInstance((FARPROC)TypeInMoveDialog, hInst);\r
DialogBoxParam(hInst, MAKEINTRESOURCE(DLG_TypeInMove),\r
- hwndMain, (DLGPROC)lpProc, (LPARAM)firstchar);\r
+ hwndMain, (DLGPROC)lpProc, (LPARAM)firstchar);\r
FreeProcInstance(lpProc);\r
}\r
}\r
\r
/*---------------------------------------------------------------------------*\\r
*\r
+ * Type-in name dialog functions\r
+ *\r
+\*---------------------------------------------------------------------------*/\r
+\r
+LRESULT CALLBACK\r
+TypeInNameDialog(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)\r
+{\r
+ char move[MSG_SIZ];\r
+ HWND hInput;\r
+\r
+ switch (message) {\r
+ case WM_INITDIALOG:\r
+ move[0] = (char) lParam;\r
+ move[1] = NULLCHAR;\r
+ CenterWindowEx(hDlg, GetWindow(hDlg, GW_OWNER), 1 );\r
+ hInput = GetDlgItem(hDlg, OPT_Name);\r
+ SetWindowText(hInput, move);\r
+ SetFocus(hInput);\r
+ SendMessage(hInput, EM_SETSEL, (WPARAM)9999, (LPARAM)9999);\r
+ return FALSE;\r
+\r
+ case WM_COMMAND:\r
+ switch (LOWORD(wParam)) {\r
+ case IDOK:\r
+ GetDlgItemText(hDlg, OPT_Name, move, sizeof(move));\r
+ appData.userName = strdup(move);\r
+ SetUserLogo();\r
+\r
+ EndDialog(hDlg, TRUE);\r
+ return TRUE;\r
+ case IDCANCEL:\r
+ EndDialog(hDlg, FALSE);\r
+ return TRUE;\r
+ default:\r
+ break;\r
+ }\r
+ break;\r
+ }\r
+ return FALSE;\r
+}\r
+\r
+VOID\r
+PopUpNameDialog(char firstchar)\r
+{\r
+ FARPROC lpProc;\r
+\r
+ lpProc = MakeProcInstance((FARPROC)TypeInNameDialog, hInst);\r
+ DialogBoxParam(hInst, MAKEINTRESOURCE(DLG_TypeInName),\r
+ hwndMain, (DLGPROC)lpProc, (LPARAM)firstchar);\r
+ FreeProcInstance(lpProc);\r
+}\r
+\r
+/*---------------------------------------------------------------------------*\\r
+ *\r
* Error dialogs\r
- * \r
+ *\r
\*---------------------------------------------------------------------------*/\r
\r
/* Nonmodal error box */\r
LRESULT CALLBACK ErrorDialog(HWND hDlg, UINT message,\r
- WPARAM wParam, LPARAM lParam);\r
+ WPARAM wParam, LPARAM lParam);\r
\r
VOID\r
ErrorPopUp(char *title, char *content)\r
while (*p) {\r
if (*p == '\n') {\r
if (modal) {\r
- *q++ = ' ';\r
- p++;\r
+ *q++ = ' ';\r
+ p++;\r
} else {\r
- *q++ = '\r';\r
- *q++ = *p++;\r
+ *q++ = '\r';\r
+ *q++ = *p++;\r
}\r
} else {\r
*q++ = *p++;\r
*q = NULLCHAR;\r
strncpy(errorTitle, title, sizeof(errorTitle));\r
errorTitle[sizeof(errorTitle) - 1] = '\0';\r
- \r
+\r
if (modal) {\r
MessageBox(NULL, errorMessage, errorTitle, MB_OK|MB_ICONEXCLAMATION);\r
} else {\r
lpProc = MakeProcInstance((FARPROC)ErrorDialog, hInst);\r
CreateDialog(hInst, MAKEINTRESOURCE(DLG_Error),\r
- hwndMain, (DLGPROC)lpProc);\r
+ hwndMain, (DLGPROC)lpProc);\r
FreeProcInstance(lpProc);\r
}\r
}\r
switch (message) {\r
case WM_INITDIALOG:\r
GetWindowRect(hDlg, &rChild);\r
+\r
+ /*\r
SetWindowPos(hDlg, NULL, rChild.left,\r
- rChild.top + boardRect.top - (rChild.bottom - rChild.top), \r
+ rChild.top + boardRect.top - (rChild.bottom - rChild.top),\r
0, 0, SWP_NOZORDER|SWP_NOSIZE);\r
+ */\r
+\r
+ /*\r
+ [AS] It seems that the above code wants to move the dialog up in the "caption\r
+ area" of the main window, but it uses the dialog height as an hard-coded constant,\r
+ and it doesn't work when you resize the dialog.\r
+ For now, just give it a default position.\r
+ */\r
+ SetWindowPos(hDlg, NULL, boardRect.left+8, boardRect.top+8, 0, 0, SWP_NOZORDER|SWP_NOSIZE);\r
+\r
errorDialog = hDlg;\r
SetWindowText(hDlg, errorTitle);\r
hwndText = GetDlgItem(hDlg, OPT_ErrorText);\r
return FALSE;\r
}\r
\r
+#ifdef GOTHIC\r
+HWND gothicDialog = NULL;\r
+\r
+LRESULT CALLBACK\r
+GothicDialog(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)\r
+{\r
+ HANDLE hwndText;\r
+ RECT rChild;\r
+ int height = GetSystemMetrics(SM_CYCAPTION)+GetSystemMetrics(SM_CYFRAME);\r
+\r
+ switch (message) {\r
+ case WM_INITDIALOG:\r
+ GetWindowRect(hDlg, &rChild);\r
+\r
+ SetWindowPos(hDlg, NULL, boardX, boardY-height, winWidth, height,\r
+ SWP_NOZORDER);\r
+\r
+ /*\r
+ [AS] It seems that the above code wants to move the dialog up in the "caption\r
+ area" of the main window, but it uses the dialog height as an hard-coded constant,\r
+ and it doesn't work when you resize the dialog.\r
+ For now, just give it a default position.\r
+ */\r
+ gothicDialog = hDlg;\r
+ SetWindowText(hDlg, errorTitle);\r
+ hwndText = GetDlgItem(hDlg, OPT_ErrorText);\r
+ SetDlgItemText(hDlg, OPT_ErrorText, errorMessage);\r
+ return FALSE;\r
+\r
+ case WM_COMMAND:\r
+ switch (LOWORD(wParam)) {\r
+ case IDOK:\r
+ case IDCANCEL:\r
+ if (errorDialog == hDlg) errorDialog = NULL;\r
+ DestroyWindow(hDlg);\r
+ return TRUE;\r
+\r
+ default:\r
+ break;\r
+ }\r
+ break;\r
+ }\r
+ return FALSE;\r
+}\r
+\r
+VOID\r
+GothicPopUp(char *title, VariantClass variant)\r
+{\r
+ FARPROC lpProc;\r
+ static char *lastTitle;\r
+\r
+ strncpy(errorTitle, title, sizeof(errorTitle));\r
+ errorTitle[sizeof(errorTitle) - 1] = '\0';\r
+\r
+ if(lastTitle != title && gothicDialog != NULL) {\r
+ DestroyWindow(gothicDialog);\r
+ gothicDialog = NULL;\r
+ }\r
+ if(variant != VariantNormal && gothicDialog == NULL) {\r
+ title = lastTitle;\r
+ lpProc = MakeProcInstance((FARPROC)GothicDialog, hInst);\r
+ CreateDialog(hInst, MAKEINTRESOURCE(DLG_Error),\r
+ hwndMain, (DLGPROC)lpProc);\r
+ FreeProcInstance(lpProc);\r
+ }\r
+}\r
+#endif\r
+\r
/*---------------------------------------------------------------------------*\\r
*\r
* Ics Interaction console functions\r
void\r
ParseIcsTextMenu(char *icsTextMenuString)\r
{\r
- int flags = 0;\r
+// int flags = 0;\r
IcsTextMenuEntry *e = icsTextMenuEntry;\r
char *p = icsTextMenuString;\r
while (e->item != NULL && e < icsTextMenuEntry + ICS_TEXT_MENU_SIZE) {\r
c = ';';\r
t = strchr(s + 1, c);\r
if (t == NULL) {\r
- c = '\n';\r
- t = strchr(s + 1, c);\r
+ c = '\n';\r
+ t = strchr(s + 1, c);\r
}\r
if (t != NULL) *t = NULLCHAR;\r
e->item = strdup(p);\r
p = t + 1;\r
}\r
e++;\r
- } \r
+ }\r
}\r
\r
HMENU\r
AppendMenu(h, MF_SEPARATOR, 0, 0);\r
} else {\r
if (e->item[0] == '|') {\r
- AppendMenu(h, MF_STRING|MF_MENUBARBREAK,\r
- IDM_CommandX + i, &e->item[1]);\r
+ AppendMenu(h, MF_STRING|MF_MENUBARBREAK,\r
+ IDM_CommandX + i, &e->item[1]);\r
} else {\r
- AppendMenu(h, MF_STRING, IDM_CommandX + i, e->item);\r
+ AppendMenu(h, MF_STRING, IDM_CommandX + i, e->item);\r
}\r
}\r
e++;\r
i++;\r
- } \r
+ }\r
return hmenu;\r
}\r
\r
SetFocus(hInput);\r
}\r
return;\r
- } \r
+ }\r
SendMessage(hwnd, EM_EXGETSEL, 0, (LPARAM)&sel);\r
if (sel.cpMin == sel.cpMax) {\r
/* Expand to surrounding word */\r
}\r
}\r
\r
-LRESULT CALLBACK \r
+LRESULT CALLBACK\r
ConsoleTextSubclass(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)\r
{\r
HWND hInput;\r
}\r
break;\r
case WM_CHAR:\r
+ if(wParam != '\022') {\r
if (wParam == '\t') {\r
if (GetKeyState(VK_SHIFT) < 0) {\r
- /* shifted */\r
- if (IsIconic(hwndMain)) ShowWindow(hwndMain, SW_RESTORE);\r
- if (buttonDesc[0].hwnd) {\r
- SetFocus(buttonDesc[0].hwnd);\r
- } else {\r
- SetFocus(hwndMain);\r
- }\r
+ /* shifted */\r
+ if (IsIconic(hwndMain)) ShowWindow(hwndMain, SW_RESTORE);\r
+ if (buttonDesc[0].hwnd) {\r
+ SetFocus(buttonDesc[0].hwnd);\r
+ } else {\r
+ SetFocus(hwndMain);\r
+ }\r
} else {\r
- /* unshifted */\r
- SetFocus(GetDlgItem(hwndConsole, OPT_ConsoleInput));\r
+ /* unshifted */\r
+ SetFocus(GetDlgItem(hwndConsole, OPT_ConsoleInput));\r
}\r
} else {\r
hInput = GetDlgItem(hwndConsole, OPT_ConsoleInput);\r
- SetFocus(hInput);\r
+ JAWS_DELETE( SetFocus(hInput); )\r
SendMessage(hInput, message, wParam, lParam);\r
}\r
return 0;\r
- case WM_PASTE:\r
- hInput = GetDlgItem(hwndConsole, OPT_ConsoleInput);\r
- SetFocus(hInput);\r
- return SendMessage(hInput, message, wParam, lParam);\r
- case WM_MBUTTONDOWN:\r
- return SendMessage(hwnd, WM_COMMAND, MAKEWPARAM(IDM_QuickPaste, 0), 0);\r
- case WM_RBUTTONDOWN:\r
- if (!(GetKeyState(VK_SHIFT) & ~1)) {\r
- /* Move selection here if it was empty */\r
- POINT pt;\r
- pt.x = LOWORD(lParam);\r
- pt.y = HIWORD(lParam);\r
- SendMessage(hwnd, EM_EXGETSEL, 0, (LPARAM)&sel);\r
- if (sel.cpMin == sel.cpMax) {\r
- sel.cpMin = SendMessage(hwnd, EM_CHARFROMPOS, 0, (LPARAM)&pt); /*doc is wrong*/\r
- sel.cpMax = sel.cpMin;\r
- SendMessage(hwnd, EM_EXSETSEL, 0, (LPARAM)&sel);\r
- }\r
- SendMessage(hwnd, EM_HIDESELECTION, FALSE, FALSE);\r
- }\r
- return 0;\r
+ } // [HGM] navigate: for Ctrl+R, flow into nex case (moved up here) to summon up menu\r
case WM_RBUTTONUP:\r
if (GetKeyState(VK_SHIFT) & ~1) {\r
- SendDlgItemMessage(hwndConsole, OPT_ConsoleText, \r
+ SendDlgItemMessage(hwndConsole, OPT_ConsoleText,\r
WM_COMMAND, MAKEWPARAM(IDM_QuickPaste, 0), 0);\r
} else {\r
POINT pt;\r
MenuPopup(hwnd, pt, hmenu, -1);\r
}\r
return 0;\r
+ case WM_PASTE:\r
+ hInput = GetDlgItem(hwndConsole, OPT_ConsoleInput);\r
+ SetFocus(hInput);\r
+ return SendMessage(hInput, message, wParam, lParam);\r
+ case WM_MBUTTONDOWN:\r
+ return SendMessage(hwnd, WM_COMMAND, MAKEWPARAM(IDM_QuickPaste, 0), 0);\r
+ case WM_RBUTTONDOWN:\r
+ if (!(GetKeyState(VK_SHIFT) & ~1)) {\r
+ /* Move selection here if it was empty */\r
+ POINT pt;\r
+ pt.x = LOWORD(lParam);\r
+ pt.y = HIWORD(lParam);\r
+ SendMessage(hwnd, EM_EXGETSEL, 0, (LPARAM)&sel);\r
+ if (sel.cpMin == sel.cpMax) {\r
+ sel.cpMin = SendMessage(hwnd, EM_CHARFROMPOS, 0, (LPARAM)&pt); /*doc is wrong*/\r
+ sel.cpMax = sel.cpMin;\r
+ SendMessage(hwnd, EM_EXSETSEL, 0, (LPARAM)&sel);\r
+ }\r
+ SendMessage(hwnd, EM_HIDESELECTION, FALSE, FALSE);\r
+ }\r
+ return 0;\r
case WM_COMMAND:\r
switch (LOWORD(wParam)) {\r
case IDM_QuickPaste:\r
{\r
SendMessage(hwnd, EM_EXGETSEL, 0, (LPARAM)&sel);\r
- if (sel.cpMin == sel.cpMax) {\r
- MessageBeep(MB_ICONEXCLAMATION);\r
+ if (sel.cpMin == sel.cpMax) {\r
+ MessageBeep(MB_ICONEXCLAMATION);\r
return 0;\r
- }\r
- SendMessage(hwnd, WM_COPY, 0, 0);\r
- hInput = GetDlgItem(hwndConsole, OPT_ConsoleInput);\r
+ }\r
+ SendMessage(hwnd, WM_COPY, 0, 0);\r
+ hInput = GetDlgItem(hwndConsole, OPT_ConsoleInput);\r
SendMessage(hInput, WM_PASTE, 0, 0);\r
SetFocus(hInput);\r
return 0;\r
return 0;\r
default:\r
{\r
- int i = LOWORD(wParam) - IDM_CommandX;\r
- if (i >= 0 && i < ICS_TEXT_MENU_SIZE &&\r
- icsTextMenuEntry[i].command != NULL) {\r
- CommandX(hwnd, icsTextMenuEntry[i].command,\r
- icsTextMenuEntry[i].getname,\r
- icsTextMenuEntry[i].immediate);\r
- return 0;\r
- }\r
+ int i = LOWORD(wParam) - IDM_CommandX;\r
+ if (i >= 0 && i < ICS_TEXT_MENU_SIZE &&\r
+ icsTextMenuEntry[i].command != NULL) {\r
+ CommandX(hwnd, icsTextMenuEntry[i].command,\r
+ icsTextMenuEntry[i].getname,\r
+ icsTextMenuEntry[i].immediate);\r
+ return 0;\r
+ }\r
}\r
break;\r
}\r
}\r
switch (wParam) {\r
case '\r': /* Enter key */\r
- is->count = GetWindowText(hwnd, is->buf, INPUT_SOURCE_BUF_SIZE-1); \r
+ is->count = GetWindowText(hwnd, is->buf, INPUT_SOURCE_BUF_SIZE-1);\r
if (consoleEcho) SaveInHistory(is->buf);\r
is->buf[is->count++] = '\n';\r
is->buf[is->count] = NULLCHAR;\r
SendMessage(hwndMain, WM_USER_Input, 0, (LPARAM) is);\r
if (consoleEcho) {\r
- ConsoleOutput(is->buf, is->count, TRUE);\r
+ ConsoleOutput(is->buf, is->count, TRUE);\r
} else if (appData.localLineEditing) {\r
- ConsoleOutput("\n", 1, TRUE);\r
+ ConsoleOutput("\n", 1, TRUE);\r
}\r
/* fall thru */\r
case '\033': /* Escape key */\r
if (consoleEcho) {\r
cf.crTextColor = textAttribs[ColorNormal].color;\r
} else {\r
- cf.crTextColor = COLOR_ECHOOFF;\r
+ cf.crTextColor = COLOR_ECHOOFF;\r
}\r
cf.dwEffects = textAttribs[ColorNormal].effects;\r
SendMessage(hwnd, EM_SETCHARFORMAT, SCF_ALL, (LPARAM)&cf);\r
return 0;\r
case '\t': /* Tab key */\r
if (GetKeyState(VK_SHIFT) < 0) {\r
- /* shifted */\r
- SetFocus(GetDlgItem(hwndConsole, OPT_ConsoleText));\r
+ /* shifted */\r
+ SetFocus(GetDlgItem(hwndConsole, OPT_ConsoleText));\r
} else {\r
- /* unshifted */\r
- if (IsIconic(hwndMain)) ShowWindow(hwndMain, SW_RESTORE);\r
- if (buttonDesc[0].hwnd) {\r
- SetFocus(buttonDesc[0].hwnd);\r
- } else {\r
- SetFocus(hwndMain);\r
- }\r
+ /* unshifted */\r
+ if (IsIconic(hwndMain)) ShowWindow(hwndMain, SW_RESTORE);\r
+ if (buttonDesc[0].hwnd) {\r
+ SetFocus(buttonDesc[0].hwnd);\r
+ } else {\r
+ SetFocus(hwndMain);\r
+ }\r
}\r
return 0;\r
case '\023': /* Ctrl+S */\r
case '\021': /* Ctrl+Q */\r
quoteNextChar = TRUE;\r
return 0;\r
+ JAWS_REPLAY\r
default:\r
break;\r
}\r
GetWindowText(hwnd, buf, MSG_SIZ);\r
p = PrevInHistory(buf);\r
if (p != NULL) {\r
- SetWindowText(hwnd, p);\r
- sel.cpMin = 999999;\r
- sel.cpMax = 999999;\r
- SendMessage(hwnd, EM_EXSETSEL, 0, (LPARAM)&sel);\r
+ SetWindowText(hwnd, p);\r
+ sel.cpMin = 999999;\r
+ sel.cpMax = 999999;\r
+ SendMessage(hwnd, EM_EXSETSEL, 0, (LPARAM)&sel);\r
return 0;\r
}\r
break;\r
case VK_DOWN:\r
p = NextInHistory();\r
if (p != NULL) {\r
- SetWindowText(hwnd, p);\r
- sel.cpMin = 999999;\r
- sel.cpMax = 999999;\r
- SendMessage(hwnd, EM_EXSETSEL, 0, (LPARAM)&sel);\r
+ SetWindowText(hwnd, p);\r
+ sel.cpMin = 999999;\r
+ sel.cpMax = 999999;\r
+ SendMessage(hwnd, EM_EXSETSEL, 0, (LPARAM)&sel);\r
return 0;\r
}\r
break;\r
}\r
break;\r
case WM_MBUTTONDOWN:\r
- SendDlgItemMessage(hwndConsole, OPT_ConsoleText, \r
+ SendDlgItemMessage(hwndConsole, OPT_ConsoleText,\r
WM_COMMAND, MAKEWPARAM(IDM_QuickPaste, 0), 0);\r
break;\r
case WM_RBUTTONUP:\r
if (GetKeyState(VK_SHIFT) & ~1) {\r
- SendDlgItemMessage(hwndConsole, OPT_ConsoleText, \r
+ SendDlgItemMessage(hwndConsole, OPT_ConsoleText,\r
WM_COMMAND, MAKEWPARAM(IDM_QuickPaste, 0), 0);\r
} else {\r
POINT pt;\r
}\r
return 0;\r
case WM_COMMAND:\r
- switch (LOWORD(wParam)) { \r
+ switch (LOWORD(wParam)) {\r
case IDM_Undo:\r
SendMessage(hwnd, EM_UNDO, 0, 0);\r
return 0;\r
LRESULT CALLBACK\r
ConsoleWndProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)\r
{\r
- static HWND hText, hInput, hFocus;\r
- InputSource *is = consoleInputSource;\r
+ static SnapData sd;\r
+ static HWND hText, hInput /*, hFocus*/;\r
+// InputSource *is = consoleInputSource;\r
RECT rect;\r
static int sizeX, sizeY;\r
int newSizeX, newSizeY;\r
MINMAXINFO *mmi;\r
\r
switch (message) {\r
+ case WM_NOTIFY:\r
+ if (((NMHDR*)lParam)->code == EN_LINK)\r
+ {\r
+ ENLINK *pLink = (ENLINK*)lParam;\r
+ if (pLink->msg == WM_LBUTTONUP)\r
+ {\r
+ TEXTRANGE tr;\r
+\r
+ tr.chrg = pLink->chrg;\r
+ tr.lpstrText = malloc(1+tr.chrg.cpMax-tr.chrg.cpMin);\r
+ hText = GetDlgItem(hDlg, OPT_ConsoleText);\r
+ SendMessage(hText, EM_GETTEXTRANGE, 0, (LPARAM)&tr);\r
+ ShellExecute(NULL, "open", tr.lpstrText, NULL, NULL, SW_SHOW);\r
+ free(tr.lpstrText);\r
+ }\r
+ }\r
+ break;\r
case WM_INITDIALOG: /* message: initialize dialog box */\r
hwndConsole = hDlg;\r
hText = GetDlgItem(hDlg, OPT_ConsoleText);\r
GetClientRect(hDlg, &rect);\r
sizeX = rect.right;\r
sizeY = rect.bottom;\r
- if (consoleX != CW_USEDEFAULT && consoleY != CW_USEDEFAULT &&\r
- consoleW != CW_USEDEFAULT && consoleH != CW_USEDEFAULT) {\r
+ if (wpConsole.x != CW_USEDEFAULT && wpConsole.y != CW_USEDEFAULT &&\r
+ wpConsole.width != CW_USEDEFAULT && wpConsole.height != CW_USEDEFAULT) {\r
WINDOWPLACEMENT wp;\r
- EnsureOnScreen(&consoleX, &consoleY);\r
+ EnsureOnScreen(&wpConsole.x, &wpConsole.y, 0, 0);\r
wp.length = sizeof(WINDOWPLACEMENT);\r
wp.flags = 0;\r
wp.showCmd = SW_SHOW;\r
wp.ptMaxPosition.x = wp.ptMaxPosition.y = 0;\r
- wp.rcNormalPosition.left = consoleX;\r
- wp.rcNormalPosition.right = consoleX + consoleW;\r
- wp.rcNormalPosition.top = consoleY;\r
- wp.rcNormalPosition.bottom = consoleY + consoleH;\r
+ wp.rcNormalPosition.left = wpConsole.x;\r
+ wp.rcNormalPosition.right = wpConsole.x + wpConsole.width;\r
+ wp.rcNormalPosition.top = wpConsole.y;\r
+ wp.rcNormalPosition.bottom = wpConsole.y + wpConsole.height;\r
SetWindowPlacement(hDlg, &wp);\r
}\r
+#if 1\r
+ // [HGM] Chessknight's change 2004-07-13\r
+ else { /* Determine Defaults */\r
+ WINDOWPLACEMENT wp;\r
+ wpConsole.x = winWidth + 1;\r
+ wpConsole.y = boardY;\r
+ wpConsole.width = screenWidth - winWidth;\r
+ wpConsole.height = winHeight;\r
+ EnsureOnScreen(&wpConsole.x, &wpConsole.y, 0, 0);\r
+ wp.length = sizeof(WINDOWPLACEMENT);\r
+ wp.flags = 0;\r
+ wp.showCmd = SW_SHOW;\r
+ wp.ptMaxPosition.x = wp.ptMaxPosition.y = 0;\r
+ wp.rcNormalPosition.left = wpConsole.x;\r
+ wp.rcNormalPosition.right = wpConsole.x + wpConsole.width;\r
+ wp.rcNormalPosition.top = wpConsole.y;\r
+ wp.rcNormalPosition.bottom = wpConsole.y + wpConsole.height;\r
+ SetWindowPlacement(hDlg, &wp);\r
+ }\r
+#endif\r
return FALSE;\r
\r
case WM_SETFOCUS:\r
newTextWidth = rectText.right - rectText.left + newSizeX - sizeX;\r
newTextHeight = rectText.bottom - rectText.top + newSizeY - sizeY;\r
if (newTextHeight < 0) {\r
- newSizeY += -newTextHeight;\r
+ newSizeY += -newTextHeight;\r
newTextHeight = 0;\r
}\r
SetWindowPos(hText, NULL, 0, 0,\r
- newTextWidth, newTextHeight, SWP_NOZORDER|SWP_NOMOVE);\r
+ newTextWidth, newTextHeight, SWP_NOZORDER|SWP_NOMOVE);\r
GetWindowRect(hInput, &rectInput); /* gives screen coords */\r
pt.x = rectInput.left;\r
pt.y = rectInput.top + newSizeY - sizeY;\r
ScreenToClient(hDlg, &pt);\r
- SetWindowPos(hInput, NULL, \r
- pt.x, pt.y, /* needs client coords */ \r
- rectInput.right - rectInput.left + newSizeX - sizeX,\r
- rectInput.bottom - rectInput.top, SWP_NOZORDER);\r
+ SetWindowPos(hInput, NULL,\r
+ pt.x, pt.y, /* needs client coords */\r
+ rectInput.right - rectInput.left + newSizeX - sizeX,\r
+ rectInput.bottom - rectInput.top, SWP_NOZORDER);\r
}\r
sizeX = newSizeX;\r
sizeY = newSizeY;\r
mmi->ptMinTrackSize.x = 100;\r
mmi->ptMinTrackSize.y = 100;\r
break;\r
+\r
+ /* [AS] Snapping */\r
+ case WM_ENTERSIZEMOVE:\r
+ return OnEnterSizeMove( &sd, hDlg, wParam, lParam );\r
+\r
+ case WM_SIZING:\r
+ return OnSizing( &sd, hDlg, wParam, lParam );\r
+\r
+ case WM_MOVING:\r
+ return OnMoving( &sd, hDlg, wParam, lParam );\r
+\r
+ case WM_EXITSIZEMOVE:\r
+ return OnExitSizeMove( &sd, hDlg, wParam, lParam );\r
}\r
+\r
return DefWindowProc(hDlg, message, wParam, lParam);\r
}\r
\r
VOID\r
ConsoleCreate()\r
{\r
- HWND hCons;\r
+ HWND hCons, hText;\r
+ WORD wMask;\r
if (hwndConsole) return;\r
hCons = CreateDialog(hInst, szConsoleName, 0, NULL);\r
SendMessage(hCons, WM_INITDIALOG, 0, 0);\r
+\r
+ // make the text item in the console do URL links\r
+ hText = GetDlgItem(hCons, OPT_ConsoleText);\r
+ wMask = SendMessage(hText, EM_GETEVENTMASK, 0, 0L);\r
+ SendMessage(hText, EM_SETEVENTMASK, 0, wMask | ENM_LINK);\r
+ SendMessage(hText, EM_AUTOURLDETECT, TRUE, 0L);\r
}\r
\r
\r
while (length--) {\r
if (*p == '\n') {\r
if (*++p) {\r
- *q++ = '\r';\r
- *q++ = '\n';\r
+ *q++ = '\r';\r
+ *q++ = '\n';\r
} else {\r
- delayLF = 1;\r
+ delayLF = 1;\r
}\r
} else if (*p == '\007') {\r
MyPlaySound(&sounds[(int)SoundBell]);\r
\r
\r
void\r
+DisplayHoldingsCount(HDC hdc, int x, int y, int rightAlign, int copyNumber)\r
+{\r
+ char buf[100];\r
+ char *str;\r
+ COLORREF oldFg, oldBg;\r
+ HFONT oldFont;\r
+ RECT rect;\r
+\r
+ if(copyNumber > 1) sprintf(buf, "%d", copyNumber); else buf[0] = 0;\r
+\r
+ oldFg = SetTextColor(hdc, RGB(255, 255, 255)); /* white */\r
+ oldBg = SetBkColor(hdc, RGB(0, 0, 0)); /* black */\r
+ oldFont = SelectObject(hdc, font[boardSize][CLOCK_FONT]->hf);\r
+\r
+ rect.left = x;\r
+ rect.right = x + squareSize;\r
+ rect.top = y;\r
+ rect.bottom = y + squareSize;\r
+ str = buf;\r
+\r
+ ExtTextOut(hdc, x + MESSAGE_LINE_LEFTMARGIN\r
+ + (rightAlign ? (squareSize*2)/3 : 0),\r
+ y, ETO_CLIPPED|ETO_OPAQUE,\r
+ &rect, str, strlen(str), NULL);\r
+\r
+ (void) SetTextColor(hdc, oldFg);\r
+ (void) SetBkColor(hdc, oldBg);\r
+ (void) SelectObject(hdc, oldFont);\r
+}\r
+\r
+void\r
DisplayAClock(HDC hdc, int timeRemaining, int highlight,\r
- RECT *rect, char *color)\r
+ RECT *rect, char *color, char *flagFell)\r
{\r
char buf[100];\r
char *str;\r
\r
if (appData.clockMode) {\r
if (tinyLayout)\r
- sprintf(buf, "%c %s", color[0], TimeString(timeRemaining));\r
+ sprintf(buf, "%c %s %s", color[0], TimeString(timeRemaining), flagFell);\r
else\r
- sprintf(buf, "%s: %s", color, TimeString(timeRemaining));\r
+ sprintf(buf, "%s:%c%s %s", color, (logoHeight>0 ? 0 : ' '), TimeString(timeRemaining), flagFell);\r
str = buf;\r
} else {\r
str = color;\r
}\r
oldFont = SelectObject(hdc, font[boardSize][CLOCK_FONT]->hf);\r
\r
- ExtTextOut(hdc, rect->left + MESSAGE_LINE_LEFTMARGIN,\r
- rect->top, ETO_CLIPPED|ETO_OPAQUE,\r
- rect, str, strlen(str), NULL);\r
+ JAWS_SILENCE\r
\r
+ ExtTextOut(hdc, rect->left + MESSAGE_LINE_LEFTMARGIN,\r
+ rect->top, ETO_CLIPPED|ETO_OPAQUE,\r
+ rect, str, strlen(str), NULL);\r
+ if(logoHeight > 0 && appData.clockMode) {\r
+ RECT r;\r
+ sprintf(buf, "%s %s", buf+7, flagFell);\r
+ r.top = rect->top + logoHeight/2;\r
+ r.left = rect->left;\r
+ r.right = rect->right;\r
+ r.bottom = rect->bottom;\r
+ ExtTextOut(hdc, rect->left + MESSAGE_LINE_LEFTMARGIN,\r
+ r.top, ETO_CLIPPED|ETO_OPAQUE,\r
+ &r, str, strlen(str), NULL);\r
+ }\r
(void) SetTextColor(hdc, oldFg);\r
(void) SetBkColor(hdc, oldBg);\r
(void) SelectObject(hdc, oldFont);\r
\r
int\r
DoReadFile(HANDLE hFile, char *buf, int count, DWORD *outCount,\r
- OVERLAPPED *ovl)\r
+ OVERLAPPED *ovl)\r
{\r
int ok, err;\r
\r
+ /* [AS] */\r
+ if( count <= 0 ) {\r
+ if (appData.debugMode) {\r
+ fprintf( debugFP, "DoReadFile: trying to read past end of buffer, overflow = %d\n", count );\r
+ }\r
+\r
+ return ERROR_INVALID_USER_BUFFER;\r
+ }\r
+\r
ResetEvent(ovl->hEvent);\r
ovl->Offset = ovl->OffsetHigh = 0;\r
ok = ReadFile(hFile, buf, count, outCount, ovl);\r
if (err == ERROR_IO_PENDING) {\r
ok = GetOverlappedResult(hFile, ovl, outCount, TRUE);\r
if (ok)\r
- err = NO_ERROR;\r
+ err = NO_ERROR;\r
else\r
- err = GetLastError();\r
+ err = GetLastError();\r
}\r
}\r
return err;\r
\r
int\r
DoWriteFile(HANDLE hFile, char *buf, int count, DWORD *outCount,\r
- OVERLAPPED *ovl)\r
+ OVERLAPPED *ovl)\r
{\r
int ok, err;\r
\r
if (err == ERROR_IO_PENDING) {\r
ok = GetOverlappedResult(hFile, ovl, outCount, TRUE);\r
if (ok)\r
- err = NO_ERROR;\r
+ err = NO_ERROR;\r
else\r
- err = GetLastError();\r
+ err = GetLastError();\r
}\r
}\r
return err;\r
}\r
\r
+/* [AS] If input is line by line and a line exceed the buffer size, force an error */\r
+void CheckForInputBufferFull( InputSource * is )\r
+{\r
+ if( is->lineByLine && (is->next - is->buf) >= INPUT_SOURCE_BUF_SIZE ) {\r
+ /* Look for end of line */\r
+ char * p = is->buf;\r
+\r
+ while( p < is->next && *p != '\n' ) {\r
+ p++;\r
+ }\r
+\r
+ if( p >= is->next ) {\r
+ if (appData.debugMode) {\r
+ fprintf( debugFP, "Input line exceeded buffer size (source id=%lu)\n", is->id );\r
+ }\r
+\r
+ is->error = ERROR_BROKEN_PIPE; /* [AS] Just any non-successful code! */\r
+ is->count = (DWORD) -1;\r
+ is->next = is->buf;\r
+ }\r
+ }\r
+}\r
\r
DWORD\r
InputThread(LPVOID arg)\r
ovl.Internal = ovl.InternalHigh = ovl.Offset = ovl.OffsetHigh = 0;\r
while (is->hThread != NULL) {\r
is->error = DoReadFile(is->hFile, is->next,\r
- INPUT_SOURCE_BUF_SIZE - (is->next - is->buf),\r
- &is->count, &ovl);\r
+ INPUT_SOURCE_BUF_SIZE - (is->next - is->buf),\r
+ &is->count, &ovl);\r
if (is->error == NO_ERROR) {\r
is->next += is->count;\r
} else {\r
if (is->error == ERROR_BROKEN_PIPE) {\r
- /* Correct for MS brain damage. EOF reading a pipe is not an error. */\r
- is->count = 0;\r
+ /* Correct for MS brain damage. EOF reading a pipe is not an error. */\r
+ is->count = 0;\r
} else {\r
- is->count = (DWORD) -1;\r
+ is->count = (DWORD) -1;\r
+ /* [AS] The (is->count <= 0) check below is not useful for unsigned values! */\r
+ break;\r
}\r
}\r
+\r
+ CheckForInputBufferFull( is );\r
+\r
SendMessage(hwndMain, WM_USER_Input, 0, (LPARAM) is);\r
+\r
+ if( is->count == ((DWORD) -1) ) break; /* [AS] */\r
+\r
if (is->count <= 0) break; /* Quit on EOF or error */\r
}\r
+\r
CloseHandle(ovl.hEvent);\r
CloseHandle(is->hFile);\r
+\r
+ if (appData.debugMode) {\r
+ fprintf( debugFP, "Input thread terminated (id=%lu, error=%d, count=%ld)\n", is->id, is->error, is->count );\r
+ }\r
+\r
return 0;\r
}\r
\r
is = (InputSource *) arg;\r
while (is->hThread != NULL) {\r
is->error = ReadFile(is->hFile, is->next,\r
- INPUT_SOURCE_BUF_SIZE - (is->next - is->buf),\r
- &is->count, NULL) ? NO_ERROR : GetLastError();\r
+ INPUT_SOURCE_BUF_SIZE - (is->next - is->buf),\r
+ &is->count, NULL) ? NO_ERROR : GetLastError();\r
if (is->error == NO_ERROR) {\r
/* Change CRLF to LF */\r
if (is->next > is->buf) {\r
- p = is->next - 1;\r
- i = is->count + 1;\r
+ p = is->next - 1;\r
+ i = is->count + 1;\r
} else {\r
- p = is->next;\r
- i = is->count;\r
+ p = is->next;\r
+ i = is->count;\r
}\r
q = p;\r
prev = NULLCHAR;\r
while (i > 0) {\r
- if (prev == '\r' && *p == '\n') {\r
- *(q-1) = '\n';\r
- is->count--;\r
- } else { \r
- *q++ = *p;\r
- }\r
- prev = *p++;\r
- i--;\r
+ if (prev == '\r' && *p == '\n') {\r
+ *(q-1) = '\n';\r
+ is->count--;\r
+ } else {\r
+ *q++ = *p;\r
+ }\r
+ prev = *p++;\r
+ i--;\r
}\r
*q = NULLCHAR;\r
is->next = q;\r
} else {\r
if (is->error == ERROR_BROKEN_PIPE) {\r
- /* Correct for MS brain damage. EOF reading a pipe is not an error. */\r
- is->count = 0; \r
+ /* Correct for MS brain damage. EOF reading a pipe is not an error. */\r
+ is->count = 0;\r
} else {\r
- is->count = (DWORD) -1;\r
+ is->count = (DWORD) -1;\r
}\r
}\r
+\r
+ CheckForInputBufferFull( is );\r
+\r
SendMessage(hwndMain, WM_USER_Input, 0, (LPARAM) is);\r
+\r
+ if( is->count == ((DWORD) -1) ) break; /* [AS] */\r
+\r
if (is->count < 0) break; /* Quit on error */\r
}\r
CloseHandle(is->hFile);\r
is->error = NO_ERROR;\r
is->next += is->count;\r
if (is->count == 0 && is->second == is) {\r
- /* End of file on stderr; quit with no message */\r
- break;\r
+ /* End of file on stderr; quit with no message */\r
+ break;\r
}\r
}\r
SendMessage(hwndMain, WM_USER_Input, 0, (LPARAM) is);\r
+\r
+ if( is->count == ((DWORD) -1) ) break; /* [AS] */\r
+\r
if (is->count <= 0) break; /* Quit on EOF or error */\r
}\r
return 0;\r
char *q = p;\r
while (q < is->next) {\r
if (*q++ == '\n') {\r
- (is->func)(is, is->closure, p, q - p, NO_ERROR);\r
- p = q;\r
+ (is->func)(is, is->closure, p, q - p, NO_ERROR);\r
+ p = q;\r
}\r
}\r
+\r
/* Move any partial line to the start of the buffer */\r
q = is->buf;\r
while (p < is->next) {\r
*q++ = *p++;\r
}\r
is->next = q;\r
+\r
if (is->error != NO_ERROR || is->count == 0) {\r
/* Notify backend of the error. Note: If there was a partial\r
- line at the end, it is not flushed through. */\r
- (is->func)(is, is->closure, is->buf, is->count, is->error); \r
+ line at the end, it is not flushed through. */\r
+ (is->func)(is, is->closure, is->buf, is->count, is->error);\r
}\r
} else {\r
/* Feed in the whole chunk of input at once */\r
{ IDM_MachineWhite, MF_BYCOMMAND|MF_GRAYED },\r
{ IDM_MachineBlack, MF_BYCOMMAND|MF_GRAYED },\r
{ IDM_TwoMachines, MF_BYCOMMAND|MF_GRAYED },\r
- { IDM_AnalysisMode, MF_BYCOMMAND|MF_GRAYED },\r
+ { IDM_AnalysisMode, MF_BYCOMMAND|MF_ENABLED },\r
{ IDM_AnalyzeFile, MF_BYCOMMAND|MF_GRAYED },\r
{ IDM_TimeControl, MF_BYCOMMAND|MF_GRAYED },\r
{ IDM_MoveNow, MF_BYCOMMAND|MF_GRAYED },\r
*\r
* Front-end interface functions exported by XBoard.\r
* Functions appear in same order as prototypes in frontend.h.\r
- * \r
+ *\r
\*---------------------------------------------------------------------------*/\r
VOID\r
ModeHighlight()\r
if (pausing != prevPausing) {\r
prevPausing = pausing;\r
(void) CheckMenuItem(GetMenu(hwndMain), IDM_Pause,\r
- MF_BYCOMMAND|(pausing ? MF_CHECKED : MF_UNCHECKED));\r
+ MF_BYCOMMAND|(pausing ? MF_CHECKED : MF_UNCHECKED));\r
if (hwndPause) SetWindowText(hwndPause, pausing ? "C" : "P");\r
}\r
\r
}\r
if (prevChecked != 0)\r
(void) CheckMenuItem(GetMenu(hwndMain),\r
- prevChecked, MF_BYCOMMAND|MF_UNCHECKED);\r
+ prevChecked, MF_BYCOMMAND|MF_UNCHECKED);\r
if (nowChecked != 0)\r
(void) CheckMenuItem(GetMenu(hwndMain),\r
- nowChecked, MF_BYCOMMAND|MF_CHECKED);\r
+ nowChecked, MF_BYCOMMAND|MF_CHECKED);\r
\r
if (nowChecked == IDM_LoadGame || nowChecked == IDM_Training) {\r
- (void) EnableMenuItem(GetMenu(hwndMain), IDM_Training, \r
- MF_BYCOMMAND|MF_ENABLED);\r
+ (void) EnableMenuItem(GetMenu(hwndMain), IDM_Training,\r
+ MF_BYCOMMAND|MF_ENABLED);\r
} else {\r
- (void) EnableMenuItem(GetMenu(hwndMain), \r
- IDM_Training, MF_BYCOMMAND|MF_GRAYED);\r
+ (void) EnableMenuItem(GetMenu(hwndMain),\r
+ IDM_Training, MF_BYCOMMAND|MF_GRAYED);\r
}\r
\r
prevChecked = nowChecked;\r
+\r
+ /* [DM] icsEngineAnalyze - Do a sceure check too */\r
+ if (appData.icsActive) {\r
+ if (appData.icsEngineAnalyze) {\r
+ (void) CheckMenuItem(GetMenu(hwndMain), IDM_AnalysisMode,\r
+ MF_BYCOMMAND|MF_CHECKED);\r
+ } else {\r
+ (void) CheckMenuItem(GetMenu(hwndMain), IDM_AnalysisMode,\r
+ MF_BYCOMMAND|MF_UNCHECKED);\r
+ }\r
+ }\r
}\r
\r
VOID\r
#ifdef ZIPPY\r
if (appData.zippyPlay) {\r
SetMenuEnables(hmenu, zippyEnables);\r
+ if (!appData.noChessProgram) /* [DM] icsEngineAnalyze */\r
+ (void) EnableMenuItem(GetMenu(hwndMain), IDM_AnalysisMode,\r
+ MF_BYCOMMAND|MF_ENABLED);\r
}\r
#endif\r
}\r
SetMenuEnables(GetMenu(hwndMain), cmailEnables);\r
}\r
\r
-VOID \r
+VOID\r
SetTrainingModeOn()\r
{\r
int i;\r
} else if (appData.icsActive) {\r
if (appData.icsCommPort[0] != NULLCHAR)\r
host = "ICS";\r
- else \r
+ else\r
host = appData.icsHost;\r
sprintf(title, "%s: %s", szTitle, host);\r
} else if (appData.noChessProgram) {\r
}\r
messageText[MESSAGE_TEXT_MAX - 1] = NULLCHAR;\r
\r
- if (IsIconic(hwndMain)) return;\r
+ if (hwndMain == NULL || IsIconic(hwndMain)) return;\r
+\r
+ SAYMACHINEMOVE();\r
+\r
hdc = GetDC(hwndMain);\r
oldFont = SelectObject(hdc, font[boardSize][MESSAGE_FONT]->hf);\r
ExtTextOut(hdc, messageRect.left, messageRect.top, ETO_CLIPPED|ETO_OPAQUE,\r
- &messageRect, messageText, strlen(messageText), NULL);\r
+ &messageRect, messageText, strlen(messageText), NULL);\r
(void) SelectObject(hdc, oldFont);\r
(void) ReleaseDC(hwndMain, hdc);\r
}\r
VOID\r
DisplayError(char *str, int error)\r
{\r
- FARPROC lpProc;\r
char buf[MSG_SIZ*2], buf2[MSG_SIZ];\r
int len;\r
- char *p, *q;\r
\r
if (error == 0) {\r
strcpy(buf, str);\r
} else {\r
len = FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM,\r
- NULL, error, LANG_NEUTRAL,\r
- (LPSTR) buf2, MSG_SIZ, NULL);\r
+ NULL, error, LANG_NEUTRAL,\r
+ (LPSTR) buf2, MSG_SIZ, NULL);\r
if (len > 0) {\r
sprintf(buf, "%s:\n%s", str, buf2);\r
} else {\r
ErrorMap *em = errmap;\r
while (em->err != 0 && em->err != error) em++;\r
if (em->err != 0) {\r
- sprintf(buf, "%s:\n%s", str, em->msg);\r
+ sprintf(buf, "%s:\n%s", str, em->msg);\r
} else {\r
- sprintf(buf, "%s:\nError code %d", str, error);\r
+ sprintf(buf, "%s:\nError code %d", str, error);\r
}\r
}\r
}\r
- \r
+\r
ErrorPopUp("Error", buf);\r
}\r
\r
\r
if (error != 0) {\r
len = FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM,\r
- NULL, error, LANG_NEUTRAL,\r
- (LPSTR) buf2, MSG_SIZ, NULL);\r
+ NULL, error, LANG_NEUTRAL,\r
+ (LPSTR) buf2, MSG_SIZ, NULL);\r
if (len > 0) {\r
sprintf(buf, "%s:\n%s", str, buf2);\r
} else {\r
ErrorMap *em = errmap;\r
while (em->err != 0 && em->err != error) em++;\r
if (em->err != 0) {\r
- sprintf(buf, "%s:\n%s", str, em->msg);\r
+ sprintf(buf, "%s:\n%s", str, em->msg);\r
} else {\r
- sprintf(buf, "%s:\nError code %d", str, error);\r
+ sprintf(buf, "%s:\nError code %d", str, error);\r
}\r
}\r
str = buf;\r
}\r
if (appData.popupExitMessage) {\r
(void) MessageBox(hwndMain, str, label, MB_OK|\r
- (exitStatus ? MB_ICONSTOP : MB_ICONINFORMATION));\r
+ (exitStatus ? MB_ICONSTOP : MB_ICONINFORMATION));\r
}\r
ExitEvent(exitStatus);\r
}\r
{\r
QuestionParams qp;\r
FARPROC lpProc;\r
- \r
+\r
qp.title = title;\r
qp.question = question;\r
qp.replyPrefix = replyPrefix;\r
FreeProcInstance(lpProc);\r
}\r
\r
+/* [AS] Pick FRC position */\r
+LRESULT CALLBACK NewGameFRC_Proc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)\r
+{\r
+ static int * lpIndexFRC;\r
+ BOOL index_is_ok;\r
+ char buf[16];\r
+\r
+ switch( message )\r
+ {\r
+ case WM_INITDIALOG:\r
+ lpIndexFRC = (int *) lParam;\r
+\r
+ CenterWindow(hDlg, GetWindow(hDlg, GW_OWNER));\r
+\r
+ SendDlgItemMessage( hDlg, IDC_NFG_Edit, EM_SETLIMITTEXT, sizeof(buf)-1, 0 );\r
+ SetDlgItemInt( hDlg, IDC_NFG_Edit, *lpIndexFRC, TRUE );\r
+ SendDlgItemMessage( hDlg, IDC_NFG_Edit, EM_SETSEL, 0, -1 );\r
+ SetFocus(GetDlgItem(hDlg, IDC_NFG_Edit));\r
+\r
+ break;\r
+\r
+ case WM_COMMAND:\r
+ switch( LOWORD(wParam) ) {\r
+ case IDOK:\r
+ *lpIndexFRC = GetDlgItemInt(hDlg, IDC_NFG_Edit, &index_is_ok, TRUE );\r
+ EndDialog( hDlg, 0 );\r
+ shuffleOpenings = TRUE; /* [HGM] shuffle: switch shuffling on for as long as we stay in current variant */\r
+ return TRUE;\r
+ case IDCANCEL:\r
+ EndDialog( hDlg, 1 );\r
+ return TRUE;\r
+ case IDC_NFG_Edit:\r
+ if( HIWORD(wParam) == EN_CHANGE ) {\r
+ GetDlgItemInt(hDlg, IDC_NFG_Edit, &index_is_ok, TRUE );\r
+\r
+ EnableWindow( GetDlgItem(hDlg, IDOK), index_is_ok );\r
+ }\r
+ return TRUE;\r
+ case IDC_NFG_Random:\r
+ sprintf( buf, "%d", myrandom() ); /* [HGM] shuffle: no longer limit to 960 */\r
+ SetDlgItemText(hDlg, IDC_NFG_Edit, buf );\r
+ return TRUE;\r
+ }\r
+\r
+ break;\r
+ }\r
+\r
+ return FALSE;\r
+}\r
+\r
+int NewGameFRC()\r
+{\r
+ int result;\r
+ int index = appData.defaultFrcPosition;\r
+ FARPROC lpProc = MakeProcInstance( (FARPROC) NewGameFRC_Proc, hInst );\r
+\r
+ result = DialogBoxParam( hInst, MAKEINTRESOURCE(DLG_NewGameFRC), hwndMain, (DLGPROC)lpProc, (LPARAM)&index );\r
+\r
+ if( result == 0 ) {\r
+ appData.defaultFrcPosition = index;\r
+ }\r
+\r
+ return result;\r
+}\r
+\r
+/* [AS] Game list options */\r
+typedef struct {\r
+ char id;\r
+ char * name;\r
+} GLT_Item;\r
+\r
+static GLT_Item GLT_ItemInfo[] = {\r
+ { GLT_EVENT, "Event" },\r
+ { GLT_SITE, "Site" },\r
+ { GLT_DATE, "Date" },\r
+ { GLT_ROUND, "Round" },\r
+ { GLT_PLAYERS, "Players" },\r
+ { GLT_RESULT, "Result" },\r
+ { GLT_WHITE_ELO, "White Rating" },\r
+ { GLT_BLACK_ELO, "Black Rating" },\r
+ { GLT_TIME_CONTROL,"Time Control" },\r
+ { GLT_VARIANT, "Variant" },\r
+ { GLT_OUT_OF_BOOK,PGN_OUT_OF_BOOK },\r
+ { GLT_RESULT_COMMENT, "Result Comment" }, // [HGM] rescom\r
+ { 0, 0 }\r
+};\r
+\r
+const char * GLT_FindItem( char id )\r
+{\r
+ const char * result = 0;\r
+\r
+ GLT_Item * list = GLT_ItemInfo;\r
+\r
+ while( list->id != 0 ) {\r
+ if( list->id == id ) {\r
+ result = list->name;\r
+ break;\r
+ }\r
+\r
+ list++;\r
+ }\r
+\r
+ return result;\r
+}\r
+\r
+void GLT_AddToList( HWND hDlg, int iDlgItem, char id, int index )\r
+{\r
+ const char * name = GLT_FindItem( id );\r
+\r
+ if( name != 0 ) {\r
+ if( index >= 0 ) {\r
+ SendDlgItemMessage( hDlg, iDlgItem, LB_INSERTSTRING, index, (LPARAM) name );\r
+ }\r
+ else {\r
+ SendDlgItemMessage( hDlg, iDlgItem, LB_ADDSTRING, 0, (LPARAM) name );\r
+ }\r
+ }\r
+}\r
+\r
+void GLT_TagsToList( HWND hDlg, char * tags )\r
+{\r
+ char * pc = tags;\r
+\r
+ SendDlgItemMessage( hDlg, IDC_GameListTags, LB_RESETCONTENT, 0, 0 );\r
+\r
+ while( *pc ) {\r
+ GLT_AddToList( hDlg, IDC_GameListTags, *pc, -1 );\r
+ pc++;\r
+ }\r
+\r
+ SendDlgItemMessage( hDlg, IDC_GameListTags, LB_ADDSTRING, 0, (LPARAM) "\t --- Hidden tags ---" );\r
+\r
+ pc = GLT_ALL_TAGS;\r
+\r
+ while( *pc ) {\r
+ if( strchr( tags, *pc ) == 0 ) {\r
+ GLT_AddToList( hDlg, IDC_GameListTags, *pc, -1 );\r
+ }\r
+ pc++;\r
+ }\r
+\r
+ SendDlgItemMessage( hDlg, IDC_GameListTags, LB_SETCURSEL, 0, 0 );\r
+}\r
+\r
+char GLT_ListItemToTag( HWND hDlg, int index )\r
+{\r
+ char result = '\0';\r
+ char name[128];\r
+\r
+ GLT_Item * list = GLT_ItemInfo;\r
+\r
+ if( SendDlgItemMessage( hDlg, IDC_GameListTags, LB_GETTEXT, index, (LPARAM) name ) != LB_ERR ) {\r
+ while( list->id != 0 ) {\r
+ if( strcmp( list->name, name ) == 0 ) {\r
+ result = list->id;\r
+ break;\r
+ }\r
+\r
+ list++;\r
+ }\r
+ }\r
+\r
+ return result;\r
+}\r
+\r
+void GLT_MoveSelection( HWND hDlg, int delta )\r
+{\r
+ int idx1 = (int) SendDlgItemMessage( hDlg, IDC_GameListTags, LB_GETCURSEL, 0, 0 );\r
+ int idx2 = idx1 + delta;\r
+ int count = (int) SendDlgItemMessage( hDlg, IDC_GameListTags, LB_GETCOUNT, 0, 0 );\r
+\r
+ if( idx1 >=0 && idx1 < count && idx2 >= 0 && idx2 < count ) {\r
+ char buf[128];\r
+\r
+ SendDlgItemMessage( hDlg, IDC_GameListTags, LB_GETTEXT, idx1, (LPARAM) buf );\r
+ SendDlgItemMessage( hDlg, IDC_GameListTags, LB_DELETESTRING, idx1, 0 );\r
+ SendDlgItemMessage( hDlg, IDC_GameListTags, LB_INSERTSTRING, idx2, (LPARAM) buf );\r
+ SendDlgItemMessage( hDlg, IDC_GameListTags, LB_SETCURSEL, idx2, 0 );\r
+ }\r
+}\r
+\r
+LRESULT CALLBACK GameListOptions_Proc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)\r
+{\r
+ static char glt[64];\r
+ static char * lpUserGLT;\r
+\r
+ switch( message )\r
+ {\r
+ case WM_INITDIALOG:\r
+ lpUserGLT = (char *) lParam;\r
+\r
+ strcpy( glt, lpUserGLT );\r
+\r
+ CenterWindow(hDlg, GetWindow(hDlg, GW_OWNER));\r
+\r
+ /* Initialize list */\r
+ GLT_TagsToList( hDlg, glt );\r
+\r
+ SetFocus( GetDlgItem(hDlg, IDC_GameListTags) );\r
+\r
+ break;\r
+\r
+ case WM_COMMAND:\r
+ switch( LOWORD(wParam) ) {\r
+ case IDOK:\r
+ {\r
+ char * pc = lpUserGLT;\r
+ int idx = 0;\r
+// int cnt = (int) SendDlgItemMessage( hDlg, IDC_GameListTags, LB_GETCOUNT, 0, 0 );\r
+ char id;\r
+\r
+ do {\r
+ id = GLT_ListItemToTag( hDlg, idx );\r
+\r
+ *pc++ = id;\r
+ idx++;\r
+ } while( id != '\0' );\r
+ }\r
+ EndDialog( hDlg, 0 );\r
+ return TRUE;\r
+ case IDCANCEL:\r
+ EndDialog( hDlg, 1 );\r
+ return TRUE;\r
+\r
+ case IDC_GLT_Default:\r
+ strcpy( glt, GLT_DEFAULT_TAGS );\r
+ GLT_TagsToList( hDlg, glt );\r
+ return TRUE;\r
+\r
+ case IDC_GLT_Restore:\r
+ strcpy( glt, lpUserGLT );\r
+ GLT_TagsToList( hDlg, glt );\r
+ return TRUE;\r
+\r
+ case IDC_GLT_Up:\r
+ GLT_MoveSelection( hDlg, -1 );\r
+ return TRUE;\r
+\r
+ case IDC_GLT_Down:\r
+ GLT_MoveSelection( hDlg, +1 );\r
+ return TRUE;\r
+ }\r
+\r
+ break;\r
+ }\r
+\r
+ return FALSE;\r
+}\r
+\r
+int GameListOptions()\r
+{\r
+ char glt[64];\r
+ int result;\r
+ FARPROC lpProc = MakeProcInstance( (FARPROC) GameListOptions_Proc, hInst );\r
+\r
+ strcpy( glt, appData.gameListTags );\r
+\r
+ result = DialogBoxParam( hInst, MAKEINTRESOURCE(DLG_GameListOptions), hwndMain, (DLGPROC)lpProc, (LPARAM)glt );\r
+\r
+ if( result == 0 ) {\r
+ /* [AS] Memory leak here! */\r
+ appData.gameListTags = strdup( glt );\r
+ }\r
+\r
+ return result;\r
+}\r
+\r
\r
VOID\r
DisplayIcsInteractionTitle(char *str)\r
void\r
DrawPosition(int fullRedraw, Board board)\r
{\r
- HDCDrawPosition(NULL, (BOOLEAN) fullRedraw, board); \r
+ HDCDrawPosition(NULL, (BOOLEAN) fullRedraw, board);\r
}\r
\r
\r
{\r
HWND hwnd = GetActiveWindow();\r
EitherCommentPopUp(0, title, str, FALSE);\r
+ SAY(str);\r
SetActiveWindow(hwnd);\r
}\r
\r
static char buf[MSG_SIZ];\r
DWORD bufsiz = MSG_SIZ;\r
\r
+ if(appData.userName != NULL && appData.userName[0] != 0) {\r
+ return appData.userName; /* [HGM] username: prefer name selected by user over his system login */\r
+ }\r
if (!GetUserName(buf, &bufsiz)) {\r
/*DisplayError("Error getting user name", GetLastError());*/\r
strcpy(buf, "User");\r
StartClockTimer(long millisec)\r
{\r
clockTimerEvent = SetTimer(hwndMain, (UINT) CLOCK_TIMER_ID,\r
- (UINT) millisec, NULL);\r
+ (UINT) millisec, NULL);\r
}\r
\r
void\r
DisplayWhiteClock(long timeRemaining, int highlight)\r
{\r
HDC hdc;\r
+ char *flag = whiteFlag && gameMode == TwoMachinesPlay ? "(!)" : "";\r
+\r
+ if(appData.noGUI) return;\r
hdc = GetDC(hwndMain);\r
if (!IsIconic(hwndMain)) {\r
- DisplayAClock(hdc, timeRemaining, highlight, &whiteRect, "White");\r
+ DisplayAClock(hdc, timeRemaining, highlight,\r
+ flipClock ? &blackRect : &whiteRect, "White", flag);\r
}\r
if (highlight && iconCurrent == iconBlack) {\r
iconCurrent = iconWhite;\r
DisplayBlackClock(long timeRemaining, int highlight)\r
{\r
HDC hdc;\r
+ char *flag = blackFlag && gameMode == TwoMachinesPlay ? "(!)" : "";\r
+\r
+ if(appData.noGUI) return;\r
hdc = GetDC(hwndMain);\r
if (!IsIconic(hwndMain)) {\r
- DisplayAClock(hdc, timeRemaining, highlight, &blackRect, "Black");\r
+ DisplayAClock(hdc, timeRemaining, highlight,\r
+ flipClock ? &whiteRect : &blackRect, "Black", flag);\r
}\r
if (highlight && iconCurrent == iconWhite) {\r
iconCurrent = iconBlack;\r
StartLoadGameTimer(long millisec)\r
{\r
loadGameTimerEvent = SetTimer(hwndMain, (UINT) LOAD_GAME_TIMER_ID,\r
- (UINT) millisec, NULL);\r
+ (UINT) millisec, NULL);\r
}\r
\r
void\r
char fileTitle[MSG_SIZ];\r
\r
defName = DefaultFileName(appData.oldSaveStyle ? "gam" : "pgn");\r
- f = OpenFileDialog(hwndMain, TRUE, defName,\r
- appData.oldSaveStyle ? "gam" : "pgn",\r
- GAME_FILT, \r
- "Save Game to File", NULL, fileTitle, NULL);\r
+ f = OpenFileDialog(hwndMain, "a", defName,\r
+ appData.oldSaveStyle ? "gam" : "pgn",\r
+ GAME_FILT,\r
+ "Save Game to File", NULL, fileTitle, NULL);\r
if (f != NULL) {\r
SaveGame(f, 0, "");\r
fclose(f);\r
ScheduleDelayedEvent(DelayedEventCallback cb, long millisec)\r
{\r
if (delayedTimerEvent != 0) {\r
- if (appData.debugMode) {\r
+ if (appData.debugMode && cb != delayedTimerCallback) { // [HGM] alive: not too much debug\r
fprintf(debugFP, "ScheduleDelayedEvent: event already scheduled\n");\r
}\r
KillTimer(hwndMain, delayedTimerEvent);\r
delayedTimerEvent = 0;\r
+ if(delayedTimerCallback != cb) // [HGM] alive: do not "flush" same event, just postpone it\r
delayedTimerCallback();\r
}\r
delayedTimerCallback = cb;\r
delayedTimerEvent = SetTimer(hwndMain, (UINT) DELAYED_TIMER_ID,\r
- (UINT) millisec, NULL);\r
+ (UINT) millisec, NULL);\r
}\r
\r
DelayedEventCallback\r
}\r
}\r
\r
+DWORD GetWin32Priority(int nice)\r
+{ // [HGM] nice: translate Unix nice() value to indows priority class. (Code stolen from Polyglot 1.4w11)\r
+/*\r
+REALTIME_PRIORITY_CLASS 0x00000100\r
+HIGH_PRIORITY_CLASS 0x00000080\r
+ABOVE_NORMAL_PRIORITY_CLASS 0x00008000\r
+NORMAL_PRIORITY_CLASS 0x00000020\r
+BELOW_NORMAL_PRIORITY_CLASS 0x00004000\r
+IDLE_PRIORITY_CLASS 0x00000040\r
+*/\r
+ if (nice < -15) return 0x00000080;\r
+ if (nice < 0) return 0x00008000;\r
+ if (nice == 0) return 0x00000020;\r
+ if (nice < 15) return 0x00004000;\r
+ return 0x00000040;\r
+}\r
+\r
/* Start a child process running the given program.\r
The process's standard output can be read from "from", and its\r
standard input can be written to "to".\r
\r
/* Duplicate the read handle to the pipe, so it is not inherited. */\r
fSuccess = DuplicateHandle(GetCurrentProcess(), hChildStdoutRd,\r
- GetCurrentProcess(), &hChildStdoutRdDup, 0,\r
- FALSE, /* not inherited */\r
- DUPLICATE_SAME_ACCESS);\r
+ GetCurrentProcess(), &hChildStdoutRdDup, 0,\r
+ FALSE, /* not inherited */\r
+ DUPLICATE_SAME_ACCESS);\r
if (! fSuccess) {\r
return GetLastError();\r
}\r
\r
/* Duplicate the write handle to the pipe, so it is not inherited. */\r
fSuccess = DuplicateHandle(GetCurrentProcess(), hChildStdinWr,\r
- GetCurrentProcess(), &hChildStdinWrDup, 0,\r
- FALSE, /* not inherited */\r
- DUPLICATE_SAME_ACCESS);\r
+ GetCurrentProcess(), &hChildStdinWrDup, 0,\r
+ FALSE, /* not inherited */\r
+ DUPLICATE_SAME_ACCESS);\r
if (! fSuccess) {\r
return GetLastError();\r
}\r
siStartInfo.hStdError = hChildStdoutWr;\r
\r
fSuccess = CreateProcess(NULL,\r
- cmdLine, /* command line */\r
- NULL, /* process security attributes */\r
- NULL, /* primary thread security attrs */\r
- TRUE, /* handles are inherited */\r
- DETACHED_PROCESS|CREATE_NEW_PROCESS_GROUP,\r
- NULL, /* use parent's environment */\r
- NULL,\r
- &siStartInfo, /* STARTUPINFO pointer */\r
- &piProcInfo); /* receives PROCESS_INFORMATION */\r
+ cmdLine, /* command line */\r
+ NULL, /* process security attributes */\r
+ NULL, /* primary thread security attrs */\r
+ TRUE, /* handles are inherited */\r
+ DETACHED_PROCESS|CREATE_NEW_PROCESS_GROUP,\r
+ NULL, /* use parent's environment */\r
+ NULL,\r
+ &siStartInfo, /* STARTUPINFO pointer */\r
+ &piProcInfo); /* receives PROCESS_INFORMATION */\r
\r
err = GetLastError();\r
SetCurrentDirectory(buf); /* return to prev directory */\r
return err;\r
}\r
\r
+ if (appData.niceEngines){ // [HGM] nice: adjust engine proc priority\r
+ if(appData.debugMode) fprintf(debugFP, "nice engine proc to %d\n", appData.niceEngines);\r
+ SetPriorityClass(piProcInfo.hProcess, GetWin32Priority(appData.niceEngines));\r
+ }\r
+\r
/* Close the handles we don't need in the parent */\r
CloseHandle(piProcInfo.hThread);\r
CloseHandle(hChildStdinRd);\r
void\r
DestroyChildProcess(ProcRef pr, int/*boolean*/ signal)\r
{\r
- ChildProc *cp;\r
+ ChildProc *cp; int result;\r
\r
cp = (ChildProc *) pr;\r
if (cp == NULL) return;\r
we could arrange for this even though neither WinBoard\r
nor the chess program uses a console for stdio? */\r
/*!!if (signal) GenerateConsoleCtrlEvent(CTRL_BREAK_EVENT, cp->pid);*/\r
+\r
+ /* [AS] Special termination modes for misbehaving programs... */\r
+ if( signal == 9 ) {\r
+ result = TerminateProcess( cp->hProcess, 0 );\r
+\r
+ if ( appData.debugMode) {\r
+ fprintf( debugFP, "Terminating process %lu, result=%d\n", cp->pid, result );\r
+ }\r
+ }\r
+ else if( signal == 10 ) {\r
+ DWORD dw = WaitForSingleObject( cp->hProcess, 3*1000 ); // Wait 3 seconds at most\r
+\r
+ if( dw != WAIT_OBJECT_0 ) {\r
+ result = TerminateProcess( cp->hProcess, 0 );\r
+\r
+ if ( appData.debugMode) {\r
+ fprintf( debugFP, "Process %lu still alive after timeout, killing... result=%d\n", cp->pid, result );\r
+ }\r
+\r
+ }\r
+ }\r
+\r
CloseHandle(cp->hProcess);\r
break;\r
\r
\r
/* Make connection */\r
if (connect(s, (struct sockaddr *) &sa,\r
- sizeof(struct sockaddr_in)) == SOCKET_ERROR) {\r
+ sizeof(struct sockaddr_in)) == SOCKET_ERROR) {\r
err = WSAGetLastError();\r
WSACleanup();\r
return err;\r
strcpy(fullname, name);\r
\r
h = CreateFile(name, GENERIC_READ | GENERIC_WRITE,\r
- 0, NULL, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, NULL);\r
+ 0, NULL, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, NULL);\r
if (h == (HANDLE) -1) {\r
return GetLastError();\r
}\r
}\r
if (s == INVALID_SOCKET) {\r
if ((s = socket(PF_INET, SOCK_STREAM, 0)) == INVALID_SOCKET) {\r
- err = WSAGetLastError();\r
- WSACleanup();\r
- return err;\r
+ err = WSAGetLastError();\r
+ WSACleanup();\r
+ return err;\r
}\r
}\r
uport = (unsigned short) fromPort;\r
mysa.sin_port = htons(uport);\r
if (bind(s, (struct sockaddr *) &mysa, sizeof(struct sockaddr_in))\r
- == SOCKET_ERROR) {\r
+ == SOCKET_ERROR) {\r
err = WSAGetLastError();\r
if (err == WSAEADDRINUSE) continue;\r
WSACleanup();\r
sizeof(struct sockaddr_in)) == SOCKET_ERROR) {\r
err = WSAGetLastError();\r
if (err == WSAEADDRINUSE) {\r
- closesocket(s);\r
+ closesocket(s);\r
s = -1;\r
- continue;\r
+ continue;\r
}\r
WSACleanup();\r
return err;\r
}\r
if (s2 == INVALID_SOCKET) {\r
if ((s2 = socket(PF_INET, SOCK_STREAM, 0)) == INVALID_SOCKET) {\r
- err = WSAGetLastError();\r
- closesocket(s);\r
- WSACleanup();\r
- return err;\r
+ err = WSAGetLastError();\r
+ closesocket(s);\r
+ WSACleanup();\r
+ return err;\r
}\r
}\r
uport = (unsigned short) fromPort;\r
mysa.sin_port = htons(uport);\r
if (bind(s2, (struct sockaddr *) &mysa, sizeof(struct sockaddr_in))\r
- == SOCKET_ERROR) {\r
+ == SOCKET_ERROR) {\r
err = WSAGetLastError();\r
if (err == WSAEADDRINUSE) continue;\r
(void) closesocket(s);\r
if (listen(s2, 1) == SOCKET_ERROR) {\r
err = WSAGetLastError();\r
if (err == WSAEADDRINUSE) {\r
- closesocket(s2);\r
- s2 = INVALID_SOCKET;\r
- continue;\r
+ closesocket(s2);\r
+ s2 = INVALID_SOCKET;\r
+ continue;\r
}\r
(void) closesocket(s);\r
(void) closesocket(s2);\r
\r
InputSourceRef\r
AddInputSource(ProcRef pr, int lineByLine,\r
- InputCallback func, VOIDSTAR closure)\r
+ InputCallback func, VOIDSTAR closure)\r
{\r
- InputSource *is, *is2;\r
+ InputSource *is, *is2 = NULL;\r
ChildProc *cp = (ChildProc *) pr;\r
\r
is = (InputSource *) calloc(1, sizeof(InputSource));\r
consoleInputSource = is;\r
} else {\r
is->kind = cp->kind;\r
+ /*\r
+ [AS] Try to avoid a race condition if the thread is given control too early:\r
+ we create all threads suspended so that the is->hThread variable can be\r
+ safely assigned, then let the threads start with ResumeThread.\r
+ */\r
switch (cp->kind) {\r
case CPReal:\r
is->hFile = cp->hFrom;\r
cp->hFrom = NULL; /* now owned by InputThread */\r
is->hThread =\r
- CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) NonOvlInputThread,\r
- (LPVOID) is, 0, &is->id);\r
+ CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) NonOvlInputThread,\r
+ (LPVOID) is, CREATE_SUSPENDED, &is->id);\r
break;\r
\r
case CPComm:\r
is->hFile = cp->hFrom;\r
cp->hFrom = NULL; /* now owned by InputThread */\r
is->hThread =\r
- CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) InputThread,\r
- (LPVOID) is, 0, &is->id);\r
+ CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) InputThread,\r
+ (LPVOID) is, CREATE_SUSPENDED, &is->id);\r
break;\r
\r
case CPSock:\r
is->sock = cp->sock;\r
is->hThread =\r
- CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) SocketInputThread,\r
- (LPVOID) is, 0, &is->id);\r
+ CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) SocketInputThread,\r
+ (LPVOID) is, CREATE_SUSPENDED, &is->id);\r
break;\r
\r
case CPRcmd:\r
is2->sock = cp->sock2;\r
is2->second = is2;\r
is->hThread =\r
- CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) SocketInputThread,\r
- (LPVOID) is, 0, &is->id);\r
+ CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) SocketInputThread,\r
+ (LPVOID) is, CREATE_SUSPENDED, &is->id);\r
is2->hThread =\r
- CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) SocketInputThread,\r
- (LPVOID) is2, 0, &is2->id);\r
+ CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) SocketInputThread,\r
+ (LPVOID) is2, CREATE_SUSPENDED, &is2->id);\r
break;\r
}\r
+\r
+ if( is->hThread != NULL ) {\r
+ ResumeThread( is->hThread );\r
+ }\r
+\r
+ if( is2 != NULL && is2->hThread != NULL ) {\r
+ ResumeThread( is2->hThread );\r
+ }\r
}\r
+\r
return (InputSourceRef) is;\r
}\r
\r
if (pr == NoProc) {\r
ConsoleOutput(message, count, FALSE);\r
return count;\r
- } \r
+ }\r
\r
if (ovl.hEvent == NULL) {\r
ovl.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);\r
\r
case CPReal:\r
if (WriteFile(((ChildProc *)pr)->hTo, message, count,\r
- &dOutCount, NULL)) {\r
+ &dOutCount, NULL)) {\r
*outError = NO_ERROR;\r
outCount = (int) dOutCount;\r
} else {\r
\r
case CPComm:\r
*outError = DoWriteFile(((ChildProc *)pr)->hTo, message, count,\r
- &dOutCount, &ovl);\r
+ &dOutCount, &ovl);\r
if (*outError == NO_ERROR) {\r
outCount = (int) dOutCount;\r
}\r
\r
int\r
OutputToProcessDelayed(ProcRef pr, char *message, int count, int *outError,\r
- long msdelay)\r
+ long msdelay)\r
{\r
/* Ignore delay, not implemented for WinBoard */\r
return OutputToProcess(pr, message, count, outError);\r
\r
void\r
CmailSigHandlerCallBack(InputSourceRef isr, VOIDSTAR closure,\r
- char *buf, int count, int error)\r
+ char *buf, int count, int error)\r
{\r
DisplayFatalError("Not implemented", 0, 1);\r
}\r
{\r
if (analysisTimerEvent) return;\r
analysisTimerEvent = SetTimer(hwndMain, (UINT) ANALYSIS_TIMER_ID,\r
- (UINT) 2000, NULL);\r
+ (UINT) 2000, NULL);\r
}\r
\r
LRESULT CALLBACK\r
sizeX = rect.right;\r
sizeY = rect.bottom;\r
if (analysisX != CW_USEDEFAULT && analysisY != CW_USEDEFAULT &&\r
- analysisW != CW_USEDEFAULT && analysisH != CW_USEDEFAULT) {\r
- WINDOWPLACEMENT wp;\r
- EnsureOnScreen(&analysisX, &analysisY);\r
- wp.length = sizeof(WINDOWPLACEMENT);\r
- wp.flags = 0;\r
- wp.showCmd = SW_SHOW;\r
- wp.ptMaxPosition.x = wp.ptMaxPosition.y = 0;\r
- wp.rcNormalPosition.left = analysisX;\r
- wp.rcNormalPosition.right = analysisX + analysisW;\r
- wp.rcNormalPosition.top = analysisY;\r
- wp.rcNormalPosition.bottom = analysisY + analysisH;\r
- SetWindowPlacement(hDlg, &wp);\r
-\r
- GetClientRect(hDlg, &rect);\r
- newSizeX = rect.right;\r
- newSizeY = rect.bottom;\r
+ analysisW != CW_USEDEFAULT && analysisH != CW_USEDEFAULT) {\r
+ WINDOWPLACEMENT wp;\r
+ EnsureOnScreen(&analysisX, &analysisY, 0, 0);\r
+ wp.length = sizeof(WINDOWPLACEMENT);\r
+ wp.flags = 0;\r
+ wp.showCmd = SW_SHOW;\r
+ wp.ptMaxPosition.x = wp.ptMaxPosition.y = 0;\r
+ wp.rcNormalPosition.left = analysisX;\r
+ wp.rcNormalPosition.right = analysisX + analysisW;\r
+ wp.rcNormalPosition.top = analysisY;\r
+ wp.rcNormalPosition.bottom = analysisY + analysisH;\r
+ SetWindowPlacement(hDlg, &wp);\r
+\r
+ GetClientRect(hDlg, &rect);\r
+ newSizeX = rect.right;\r
+ newSizeY = rect.bottom;\r
ResizeEditPlusButtons(hDlg, hwndText, sizeX, sizeY,\r
- newSizeX, newSizeY);\r
- sizeX = newSizeX;\r
- sizeY = newSizeY;\r
+ newSizeX, newSizeY);\r
+ sizeX = newSizeX;\r
+ sizeY = newSizeY;\r
}\r
}\r
return FALSE;\r
case WM_COMMAND: /* message: received a command */\r
switch (LOWORD(wParam)) {\r
case IDCANCEL:\r
+ if (appData.icsActive && appData.icsEngineAnalyze) { /* [DM] icsEngineAnalyze */\r
+ ExitAnalyzeMode();\r
+ ModeHighlight();\r
+ return TRUE;\r
+ }\r
EditGameEvent();\r
return TRUE;\r
default:\r
FARPROC lpProc;\r
char *p, *q;\r
\r
+ /* [AS] */\r
+ EngineOutputPopUp();\r
+ return;\r
+\r
if (str == NULL) str = "";\r
p = (char *) malloc(2 * strlen(str) + 2);\r
q = p;\r
analysisTitle = title;\r
lpProc = MakeProcInstance((FARPROC)AnalysisDialog, hInst);\r
CreateDialog(hInst, MAKEINTRESOURCE(DLG_Analysis),\r
- hwndMain, (DLGPROC)lpProc);\r
+ hwndMain, (DLGPROC)lpProc);\r
FreeProcInstance(lpProc);\r
}\r
- analysisDialogUp = TRUE; \r
+ analysisDialogUp = TRUE;\r
}\r
\r
VOID\r
if (analysisDialog) {\r
ShowWindow(analysisDialog, SW_HIDE);\r
}\r
- analysisDialogUp = FALSE; \r
+ analysisDialogUp = FALSE;\r
}\r
\r
\r
VOID\r
ClearHighlights()\r
{\r
- highlightInfo.sq[0].x = highlightInfo.sq[0].y = \r
+ highlightInfo.sq[0].x = highlightInfo.sq[0].y =\r
highlightInfo.sq[1].x = highlightInfo.sq[1].y = -1;\r
}\r
\r
VOID\r
ClearPremoveHighlights()\r
{\r
- premoveHighlightInfo.sq[0].x = premoveHighlightInfo.sq[0].y = \r
+ premoveHighlightInfo.sq[0].x = premoveHighlightInfo.sq[0].y =\r
premoveHighlightInfo.sq[1].x = premoveHighlightInfo.sq[1].y = -1;\r
}\r
\r
POINT frames[], int * nFrames);\r
\r
\r
+void\r
+AnimateAtomicCapture(int fromX, int fromY, int toX, int toY, int nFrames)\r
+{ // [HGM] atomic: animate blast wave\r
+ int i;\r
+if(appData.debugMode) fprintf(debugFP, "exploding (%d,%d)\n", toX, toY);\r
+ explodeInfo.fromX = fromX;\r
+ explodeInfo.fromY = fromY;\r
+ explodeInfo.toX = toX;\r
+ explodeInfo.toY = toY;\r
+ for(i=1; i<nFrames; i++) {\r
+ explodeInfo.radius = (i*180)/(nFrames-1);\r
+ DrawPosition(FALSE, NULL);\r
+ Sleep(appData.animSpeed);\r
+ }\r
+ explodeInfo.radius = 0;\r
+ DrawPosition(TRUE, NULL);\r
+}\r
+\r
#define kFactor 4\r
\r
void\r
mid.y = start.y + (finish.y - start.y) / 2;\r
}\r
}\r
- \r
+\r
/* Don't use as many frames for very short moves */\r
if (abs(toY - fromY) + abs(toX - fromX) <= 2)\r
Tween(&start, &mid, &finish, kFactor - 1, frames, &nFrames);\r
animInfo.pos = finish;\r
DrawPosition(FALSE, NULL);\r
animInfo.piece = EmptySquare;\r
+ if(gameInfo.variant == VariantAtomic &&\r
+ (board[toY][toX] != EmptySquare || fromX != toX && (piece == WhitePawn || piece == BlackPawn) ) )\r
+ AnimateAtomicCapture(fromX, fromY, toX, toY, 2*nFrames);\r
}\r
\r
/* Convert board position to corner of screen rect and color */\r
int column; int row; POINT * pt;\r
{\r
if (flipView) {\r
- pt->x = lineGap + ((BOARD_SIZE-1)-column) * (squareSize + lineGap);\r
+ pt->x = lineGap + ((BOARD_WIDTH-1)-column) * (squareSize + lineGap);\r
pt->y = lineGap + row * (squareSize + lineGap);\r
} else {\r
pt->x = lineGap + column * (squareSize + lineGap);\r
- pt->y = lineGap + ((BOARD_SIZE-1)-row) * (squareSize + lineGap);\r
+ pt->y = lineGap + ((BOARD_HEIGHT-1)-row) * (squareSize + lineGap);\r
}\r
}\r
\r
count ++;\r
fraction = fraction / 2;\r
}\r
- \r
+\r
/* Midpoint */\r
frames[count] = *mid;\r
count ++;\r
- \r
+\r
/* Slow out, stepping 1/2, then 1/4, ... */\r
fraction = 2;\r
for (n = 0; n < factor; n++) {\r
}\r
\r
void\r
-HistorySet(char movelist[][2*MOVE_LEN], int first, int last, int current)\r
+HistorySet( char movelist[][2*MOVE_LEN], int first, int last, int current )\r
{\r
- /* Currently not implemented in WinBoard */\r
+#if 0\r
+ char buf[256];\r
+\r
+ sprintf( buf, "HistorySet: first=%d, last=%d, current=%d (%s)\n",\r
+ first, last, current, current >= 0 ? movelist[current] : "n/a" );\r
+\r
+ OutputDebugString( buf );\r
+#endif\r
+\r
+ MoveHistorySet( movelist, first, last, current, pvInfoList );\r
+\r
+ EvalGraphSet( first, last, current, pvInfoList );\r
}\r
\r
+void SetProgramStats( FrontEndProgramStats * stats )\r
+{\r
+#if 0\r
+ char buf[1024];\r
+\r
+ sprintf( buf, "SetStats for %d: depth=%d, nodes=%lu, score=%5.2f, time=%5.2f, pv=%s\n",\r
+ stats->which, stats->depth, stats->nodes, stats->score / 100.0, stats->time / 100.0, stats->pv == 0 ? "n/a" : stats->pv );\r
+\r
+ OutputDebugString( buf );\r
+#endif\r
\r
+ EngineOutputUpdate( stats );\r
+}\r