* WinBoard.c -- Windows NT front end to XBoard\r
*\r
* Copyright 1991 by Digital Equipment Corporation, Maynard,\r
- * Massachusetts. \r
+ * Massachusetts.\r
*\r
* Enhancements Copyright 1992-2001, 2002, 2003, 2004, 2005, 2006,\r
- * 2007, 2008, 2009, 2010, 2011, 2012 Free Software Foundation, Inc.\r
+ * 2007, 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016 Free\r
+ * Software Foundation, Inc.\r
*\r
* Enhancements Copyright 2005 Alessandro Scotti\r
*\r
#include "help.h"\r
#include "wsnap.h"\r
\r
+#define SLASH '/'\r
+#define DATADIR "~~"\r
+\r
//void InitEngineUCI( const char * iniDir, ChessProgramState * cps );\r
\r
int myrandom(void);\r
extern int whiteFlag, blackFlag;\r
Boolean flipClock = FALSE;\r
extern HANDLE chatHandle[];\r
-extern int ics_type;\r
+extern enum ICS_TYPE ics_type;\r
\r
+int MySearchPath P((char *installDir, char *name, char *fullname));\r
+int MyGetFullPathName P((char *name, char *fullname));\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 DisplayMove P((int moveNumber));\r
-Boolean ParseFEN P((Board board, int *blackPlaysFirst, char *fen));\r
void ChatPopUp P((char *s));\r
typedef struct {\r
ChessSquare piece; \r
RECT boardRect;\r
COLORREF lightSquareColor, darkSquareColor, whitePieceColor, \r
blackPieceColor, highlightSquareColor, premoveHighlightColor;\r
+COLORREF markerColor[8] = { 0x00FFFF, 0x0000FF, 0x00FF00, 0xFF0000, 0xFFFF00, 0xFF00FF, 0xFFFFFF, 0x000000 };\r
HPALETTE hPal;\r
ColorClass currentColorClass;\r
\r
static HBRUSH lightSquareBrush, darkSquareBrush,\r
blackSquareBrush, /* [HGM] for band between board and holdings */\r
explodeBrush, /* [HGM] atomic */\r
- markerBrush, /* [HGM] markers */\r
+ markerBrush[8], /* [HGM] markers */\r
whitePieceBrush, blackPieceBrush, iconBkgndBrush /*, outlineBrush*/;\r
static POINT gridEndpoints[(BOARD_RANKS + BOARD_FILES + 2) * 2];\r
static DWORD gridVertexCounts[BOARD_RANKS + BOARD_FILES + 2];\r
#if __GNUC__ && !defined(_winmajor)\r
#define oldDialog 0 /* cygwin doesn't define _winmajor; mingw does */\r
#else\r
+\r
#if defined(_winmajor)\r
#define oldDialog (_winmajor < 4)\r
#else\r
{ DLG_TimeControl, IDC_Babble, OPT_TCUseMoves, OPT_TCUseInc, OPT_TCUseFixed, \r
OPT_TCtext1, OPT_TCtext2, OPT_TCitext1, OPT_TCitext2, OPT_TCftext, GPB_Factors, IDC_Factor1, IDC_Factor2, IDOK, IDCANCEL }, \r
{ DLG_LoadOptions, OPT_Autostep, OPT_AStext1, OPT_Exact, OPT_Subset, OPT_Struct, OPT_Material, OPT_Range, OPT_Difference,\r
- OPT_elo1t, OPT_elo2t, OPT_datet, OPT_Stretch, OPT_Stretcht, OPT_Reversed, OPT_SearchMode, OPT_Mirror, OPT_thresholds, IDOK, IDCANCEL }, \r
+ OPT_elo1t, OPT_elo2t, OPT_datet, OPT_Stretch, OPT_Stretcht, OPT_Reversed, OPT_SearchMode, OPT_Mirror, OPT_thresholds,\r
+ OPT_Ranget, IDOK, IDCANCEL }, \r
{ DLG_SaveOptions, OPT_Autosave, OPT_AVPrompt, OPT_AVToFile, OPT_AVBrowse,\r
801, OPT_PGN, OPT_Old, OPT_OutOfBookInfo, IDOK, IDCANCEL }, \r
{ 1536, 1090, IDC_Directories, 1089, 1091, IDOK, IDCANCEL, 1038, IDC_IndexNr, 1037 }, \r
OPT_ChooseTellColor, OPT_ChooseChallengeColor, OPT_ChooseRequestColor,\r
OPT_ChooseSeekColor, OPT_ChooseNormalColor, OPT_ChooseBackgroundColor,\r
OPT_DefaultColors, OPT_DontColorize, IDC_Boxes, GPB_Colors, GPB_Premove,\r
- GPB_General, GPB_Alarm }, \r
+ GPB_General, GPB_Alarm, OPT_AutoCreate }, \r
{ DLG_BoardOptions, IDOK, IDCANCEL, OPT_SizeTiny, OPT_SizeTeeny, OPT_SizeDinky,\r
OPT_SizePetite, OPT_SizeSlim, OPT_SizeSmall, OPT_SizeMediocre, OPT_SizeMiddling,\r
OPT_SizeAverage, OPT_SizeModerate, OPT_SizeMedium, OPT_SizeBulky, OPT_SizeLarge,\r
\r
SizeInfo sizeInfo[] = \r
{\r
- { "tiny", 21, 0, 1, 1, 0, 0 },\r
- { "teeny", 25, 1, 1, 1, 0, 0 },\r
- { "dinky", 29, 1, 1, 1, 0, 0 },\r
- { "petite", 33, 1, 1, 1, 0, 0 },\r
- { "slim", 37, 2, 1, 0, 0, 0 },\r
- { "small", 40, 2, 1, 0, 0, 0 },\r
+ { "tiny", 21, 0, 1, 2, 0, 0 },\r
+ { "teeny", 25, 1, 1, 2, 0, 0 },\r
+ { "dinky", 29, 1, 1, 2, 0, 0 },\r
+ { "petite", 33, 1, 1, 2, 0, 0 },\r
+ { "slim", 37, 2, 1, 1, 0, 0 },\r
+ { "small", 40, 2, 1, 1, 0, 0 },\r
{ "mediocre", 45, 2, 1, 0, 0, 0 },\r
{ "middling", 49, 2, 0, 0, 0, 0 },\r
{ "average", 54, 2, 0, 0, 0, 0 },\r
WNDPROC wndproc;\r
} MyButtonDesc;\r
\r
-#define BUTTON_WIDTH (tinyLayout ? 16 : 32)\r
+#define BUTTON_WIDTH (tinyLayout == 2 ? 16 : 32)\r
#define N_BUTTONS 5\r
\r
MyButtonDesc buttonDesc[N_BUTTONS] =\r
\r
int tinyLayout = 0, smallLayout = 0;\r
#define MENU_BAR_ITEMS 9\r
-char *menuBarText[2][MENU_BAR_ITEMS+1] = {\r
+char *menuBarText[3][MENU_BAR_ITEMS+1] = {\r
{ N_("&File"), N_("&Edit"), N_("&View"), N_("&Mode"), N_("&Action"), N_("E&ngine"), N_("&Options"), N_("&Help"), NULL },\r
+ { N_("&Fil"), N_("&Ed"), N_("&Vw"), N_("&Mod"), N_("&Act"), N_("E&ng"), N_("&Opt"), N_("&Hlp"), NULL },\r
{ N_("&F"), N_("&E"), N_("&V"), N_("&M"), N_("&A"), N_("&N"), N_("&O"), N_("&H"), NULL },\r
};\r
\r
*\r
\*---------------------------------------------------------------------------*/\r
\r
+static void HandleMessage P((MSG *message));\r
+static HANDLE hAccelMain, hAccelNoAlt, hAccelNoICS;\r
+\r
int APIENTRY\r
WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,\r
LPSTR lpCmdLine, int nCmdShow)\r
{\r
MSG msg;\r
- HANDLE hAccelMain, hAccelNoAlt, hAccelNoICS;\r
// INITCOMMONCONTROLSEX ex;\r
\r
debugFP = stderr;\r
0, /* lowest message to examine */\r
0)) /* highest message to examine */\r
{\r
+ HandleMessage(&msg);\r
+ }\r
+\r
+\r
+ return (msg.wParam); /* Returns the value from PostQuitMessage */\r
+}\r
+\r
+static void\r
+HandleMessage (MSG *message)\r
+{\r
+ MSG msg = *message;\r
\r
if(msg.message == WM_CHAR && msg.wParam == '\t') {\r
// [HGM] navigate: switch between all windows with tab\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
+ return; // this message now has been processed\r
}\r
}\r
\r
if(chatHandle[i] && IsDialogMessage(chatHandle[i], &msg)) {\r
done = 1; break;\r
}\r
- if(done) continue; // [HGM] chat: end patch\r
+ if(done) return; // [HGM] chat: end patch\r
TranslateMessage(&msg); /* Translates virtual key codes */\r
DispatchMessage(&msg); /* Dispatches message to window */\r
}\r
- }\r
-\r
+}\r
\r
- return (msg.wParam); /* Returns the value from PostQuitMessage */\r
+void\r
+DoEvents ()\r
+{ /* Dispatch pending messages */\r
+ MSG msg;\r
+ while (PeekMessage(&msg, /* message structure */\r
+ NULL, /* handle of window receiving the message */\r
+ 0, /* lowest message to examine */\r
+ 0, /* highest message to examine */\r
+ PM_REMOVE))\r
+ {\r
+ HandleMessage(&msg);\r
+ }\r
}\r
\r
/*---------------------------------------------------------------------------*\\r
\r
/* Set by InitInstance, used by EnsureOnScreen */\r
int screenHeight, screenWidth;\r
+RECT screenGeometry;\r
\r
void\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
+ if (*x > screenGeometry.right - 32) *x = screenGeometry.left;\r
+ if (*y > screenGeometry.bottom - 32) *y = screenGeometry.top;\r
+ if (*x < screenGeometry.left + minX) *x = screenGeometry.left + minX;\r
+ if (*y < screenGeometry.top + minY) *y = screenGeometry.top + minY;\r
}\r
\r
VOID\r
}\r
} else if(appData.autoLogo) {\r
if(ics) { // [HGM] logo: in ICS mode second can be used for ICS\r
- sprintf(buf, "logos\\%s.bmp", appData.icsHost);\r
- cps->programLogo = LoadImage( 0, buf, IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE );\r
+ char *opponent = "";\r
+ if(gameMode == IcsPlayingWhite) opponent = gameInfo.black;\r
+ if(gameMode == IcsPlayingBlack) opponent = gameInfo.white;\r
+ sprintf(buf, "logos\\%s\\%s.bmp", appData.icsHost, opponent);\r
+ if(!*opponent || !(cps->programLogo = LoadImage( 0, buf, IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE ))) {\r
+ sprintf(buf, "logos\\%s.bmp", appData.icsHost);\r
+ cps->programLogo = LoadImage( 0, buf, IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE );\r
+ }\r
} else\r
if(appData.directory[n] && appData.directory[n][0]) {\r
SetCurrentDirectory(appData.directory[n]);\r
backTextureSquareSize = 0; // kludge to force recalculation of texturemode\r
\r
if( appData.liteBackTextureFile && appData.liteBackTextureFile[0] != NULLCHAR && appData.liteBackTextureFile[0] != '*' ) {\r
+ if(liteBackTexture) DeleteObject(liteBackTexture);\r
liteBackTexture = LoadImage( 0, appData.liteBackTextureFile, IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE );\r
liteBackTextureMode = appData.liteBackTextureMode;\r
\r
}\r
\r
if( appData.darkBackTextureFile && appData.darkBackTextureFile[0] != NULLCHAR && appData.darkBackTextureFile[0] != '*' ) {\r
+ if(darkBackTexture) DeleteObject(darkBackTexture);\r
darkBackTexture = LoadImage( 0, appData.darkBackTextureFile, IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE );\r
darkBackTextureMode = appData.darkBackTextureMode;\r
\r
}\r
}\r
\r
+#ifndef SM_CXVIRTUALSCREEN\r
+#define SM_CXVIRTUALSCREEN 78\r
+#endif\r
+#ifndef SM_CYVIRTUALSCREEN\r
+#define SM_CYVIRTUALSCREEN 79\r
+#endif\r
+#ifndef SM_XVIRTUALSCREEN \r
+#define SM_XVIRTUALSCREEN 76\r
+#endif\r
+#ifndef SM_YVIRTUALSCREEN \r
+#define SM_YVIRTUALSCREEN 77\r
+#endif\r
+\r
+VOID\r
+InitGeometry()\r
+{\r
+ screenHeight = GetSystemMetrics(SM_CYVIRTUALSCREEN);\r
+ if( !screenHeight ) screenHeight = GetSystemMetrics(SM_CYSCREEN);\r
+ screenWidth = GetSystemMetrics(SM_CXVIRTUALSCREEN);\r
+ if( !screenWidth ) screenWidth = GetSystemMetrics(SM_CXSCREEN);\r
+ screenGeometry.left = GetSystemMetrics(SM_XVIRTUALSCREEN);\r
+ screenGeometry.top = GetSystemMetrics(SM_YVIRTUALSCREEN);\r
+ screenGeometry.right = screenGeometry.left + screenWidth;\r
+ screenGeometry.bottom = screenGeometry.top + screenHeight;\r
+}\r
+\r
+ChessProgramState broadcast;\r
+\r
BOOL\r
InitInstance(HINSTANCE hInstance, int nCmdShow, LPSTR lpCmdLine)\r
{\r
\r
if (SearchPath(NULL, "WinBoard.exe", NULL, MSG_SIZ, installDir, &filepart)) {\r
*filepart = NULLCHAR;\r
+ SetCurrentDirectory(installDir);\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
+ InitGeometry();\r
InitAppData(lpCmdLine); /* Get run-time parameters */\r
/* xboard, and older WinBoards, controlled the move sound with the\r
appData.ringBellAfterMoves option. In the current WinBoard, we\r
appData.ringBellAfterMoves = TRUE;\r
}\r
if (appData.debugMode) {\r
- debugFP = fopen(appData.nameOfDebugFile, "w");\r
+ char *c = appData.nameOfDebugFile;\r
+ if(strstr(c, "///") == c) {\r
+ broadcast.which = "broadcaster";\r
+ broadcast.pr = NoProc;\r
+ broadcast.isr = NULL;\r
+ broadcast.program = c + 3;\r
+ broadcast.dir = ".";\r
+ broadcast.host = "localhost";\r
+ StartChessProgram(&broadcast);\r
+ debugFP = (FILE*) _fdopen(_open_osfhandle((long)(((ChildProc*)(broadcast.pr))->hTo), _O_WRONLY), "w");\r
+ } else\r
+ debugFP = fopen(c, "w");\r
setbuf(debugFP, NULL);\r
}\r
\r
iconBlack = LoadIcon(hInstance, "icon_black");\r
iconCurrent = iconWhite;\r
InitDrawingColors();\r
- screenHeight = GetSystemMetrics(SM_CYSCREEN);\r
- screenWidth = GetSystemMetrics(SM_CXSCREEN);\r
+\r
+ InitPosition(0); // to set nr of ranks and files, which might be non-default through command-line args\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
(void) CheckMenuItem(hmenu, IDM_SaveSettingsOnExit,\r
MF_BYCOMMAND|(saveSettingsOnExit ?\r
MF_CHECKED : MF_UNCHECKED));\r
+ EnableMenuItem(hmenu, IDM_SaveSelected, MF_GRAYED);\r
}\r
\r
//---------------------------------------------------------------------------------------------------------\r
\r
#define OPTCHAR "/"\r
#define SEPCHAR "="\r
+#define TOPLEVEL 0\r
\r
#include "args.h"\r
\r
lf->lfStrikeOut = mfp->strikeout;\r
lf->lfCharSet = mfp->charset;\r
lf->lfOutPrecision = OUT_DEFAULT_PRECIS;\r
+\r
+\r
+\r
lf->lfClipPrecision = CLIP_DEFAULT_PRECIS;\r
lf->lfQuality = DEFAULT_QUALITY;\r
lf->lfPitchAndFamily = DEFAULT_PITCH|FF_DONTCARE;\r
p = q + 1;\r
} else {\r
q = mfp->faceName;\r
+\r
while (*p && !isdigit(*p)) {\r
*q++ = *p++;\r
if (q - mfp->faceName >= sizeof(mfp->faceName))\r
COLORREF chroma = RGB(0xFF,0x00,0xFF);\r
RECT rc;\r
SIZE sz;\r
+\r
+\r
POINT pt;\r
int backColor = whitePieceColor; \r
int foreColor = blackPieceColor;\r
HBITMAP\r
DoLoadBitmap(HINSTANCE hinst, char *piece, int squareSize, char *suffix)\r
{\r
- char name[128];\r
+ char name[128], buf[MSG_SIZ];\r
\r
snprintf(name, sizeof(name)/sizeof(name[0]), "%s%d%s", piece, squareSize, suffix);\r
+ if(appData.pieceDirectory[0]) {\r
+ HBITMAP res;\r
+ snprintf(buf, MSG_SIZ, "%s\\%s.bmp", appData.pieceDirectory, name);\r
+ res = LoadImage( 0, buf, IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE );\r
+ if(res) return res;\r
+ }\r
if (gameInfo.event &&\r
strcmp(gameInfo.event, "Easter Egg Hunt") == 0 &&\r
strcmp(name, "k80s") == 0) {\r
VOID\r
InitDrawingColors()\r
{\r
+ int i;\r
if (pLogPal == NULL) {\r
/* Allocate enough memory for a logical palette with\r
* PALETTESIZE entries and set the size and version fields\r
blackPieceBrush = CreateSolidBrush(blackPieceColor);\r
iconBkgndBrush = CreateSolidBrush(GetSysColor(COLOR_BACKGROUND));\r
explodeBrush = CreateSolidBrush(highlightSquareColor); // [HGM] atomic\r
- markerBrush = CreateSolidBrush(premoveHighlightColor); // [HGM] markers\r
- /* [AS] Force rendering of the font-based pieces */\r
+ for(i=0; i<8;i++) markerBrush[i] = CreateSolidBrush(markerColor[i]); // [HGM] markers\r
+\r
+ /* [AS] Force rendering of the font-based pieces */\r
if( fontBitmapSquareSize > 0 ) {\r
fontBitmapSquareSize = 0;\r
}\r
RECT crect, wrect, oldRect;\r
int offby;\r
LOGBRUSH logbrush;\r
+ VariantClass v = gameInfo.variant;\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
+ if(boardSize == -1) return; // no size defined yet; abort (to allow early call of InitPosition)\r
+ oldBoardSize = boardSize;\r
+\r
+ if(boardSize != SizeMiddling && boardSize != SizePetite && boardSize != SizeBulky && !appData.useFont)\r
+ { // correct board size to one where built-in pieces exist\r
+ if((v == VariantCapablanca || v == VariantGothic || v == VariantGrand || v == VariantCapaRandom || v == VariantJanus || v == VariantSuper)\r
+ && (boardSize < SizePetite || boardSize > SizeBulky) // Archbishop and Chancellor available in entire middle range\r
+\r
+ || (v == VariantShogi && boardSize != SizeModerate) // Japanese-style Shogi\r
+ || v == VariantKnightmate || v == VariantSChess || v == VariantXiangqi || v == VariantSpartan\r
+ || v == VariantShatranj || v == VariantMakruk || v == VariantGreat || v == VariantFairy || v == VariantLion ) {\r
+ if(boardSize < SizeMediocre) boardSize = SizePetite; else\r
+ if(boardSize > SizeModerate) boardSize = SizeBulky; else\r
+ boardSize = SizeMiddling;\r
+ }\r
+ }\r
+ if(!appData.useFont && boardSize == SizePetite && (v == VariantKnightmate)) boardSize = SizeMiddling; // no Unicorn in Petite\r
\r
oldRect.left = wpMain.x; //[HGM] placement: remember previous window params\r
oldRect.top = wpMain.y;\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
+ border = appData.useBorder && appData.border[0] ? squareSize/2 : 0;\r
+\r
+ // [HGM] decide on tininess based on total board width rather than square size\r
+ tinyLayout = squareSize * (BOARD_WIDTH);\r
+ tinyLayout = tinyLayout < 35*8 ? 2 : tinyLayout < 43*8 ? 1 : 0;\r
\r
if( appData.overrideLineGap >= 0 && appData.overrideLineGap <= 5 ) {\r
lineGap = appData.overrideLineGap;\r
\r
if (tinyLayout != oldTinyLayout) {\r
long style = GetWindowLongPtr(hwndMain, GWL_STYLE);\r
- if (tinyLayout) {\r
+ if (tinyLayout == 2) {\r
style &= ~WS_SYSMENU;\r
InsertMenu(hmenu, IDM_Exit, MF_BYCOMMAND, IDM_Minimize,\r
"&Minimize\tCtrl+F4");\r
DrawMenuBar(hwndMain);\r
}\r
\r
- boardWidth = BoardWidth(boardSize, BOARD_WIDTH);\r
- boardHeight = BoardWidth(boardSize, BOARD_HEIGHT);\r
+ boardWidth = BoardWidth(boardSize, BOARD_WIDTH) + 2*border;\r
+ boardHeight = BoardWidth(boardSize, BOARD_HEIGHT) + 2*border;\r
\r
/* Get text area sizes */\r
hdc = GetDC(hwndMain);\r
ReleaseDC(hwndMain, hdc);\r
\r
/* Compute where everything goes */\r
- if((first.programLogo || second.programLogo) && !tinyLayout) {\r
+ if((first.programLogo || second.programLogo) && tinyLayout != 2) {\r
/* [HGM] logo: if either logo is on, reserve space for it */\r
logoHeight = 2*clockSize.cy;\r
leftLogoRect.left = OUTER_MARGIN;\r
\r
sizeInfo[boardSize].cliWidth = boardRect.right + OUTER_MARGIN;\r
sizeInfo[boardSize].cliHeight = boardRect.bottom + OUTER_MARGIN;\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
messageRect.top, BUTTON_WIDTH, messageSize.cy, hwndMain,\r
(HMENU) buttonDesc[i].id,\r
(HINSTANCE) GetWindowLongPtr(hwndMain, GWLP_HINSTANCE), NULL);\r
- if (tinyLayout) {\r
+ if (tinyLayout == 2) {\r
SendMessage(buttonDesc[i].hwnd, WM_SETFONT, \r
(WPARAM)font[boardSize][MESSAGE_FONT]->hf,\r
MAKELPARAM(FALSE, 0));\r
\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].x = boardRect.left + lineGap / 2 + border;\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)) + border;\r
gridEndpoints[i*2 + 1].x = boardRect.left + lineGap / 2 +\r
- BOARD_WIDTH * (squareSize + lineGap);\r
+ BOARD_WIDTH * (squareSize + lineGap) + border;\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].y = boardRect.top + lineGap / 2 + border;\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
+ lineGap / 2 + (i * (squareSize + lineGap)) + border;\r
gridEndpoints[i*2 + 1 + BOARD_HEIGHT*2 + 2].y =\r
- boardRect.top + BOARD_HEIGHT * (squareSize + lineGap);\r
+ boardRect.top + BOARD_HEIGHT * (squareSize + lineGap) + border;\r
gridVertexCounts[i*2] = gridVertexCounts[i*2 + 1] = 2;\r
}\r
}\r
piece = (ChessSquare) ((int) piece + 1)) {\r
if (pieceBitmap[i][piece] != NULL)\r
DeleteObject(pieceBitmap[i][piece]);\r
+ pieceBitmap[i][piece] = NULL;\r
}\r
}\r
\r
fontBitmapSquareSize = 0; /* [HGM] render: make sure pieces will be recreated, as we might need others now */\r
+\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][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][WhiteAmazon] = DoLoadBitmap(hInst, "l", squareSize, "s");\r
+ pieceBitmap[1][WhiteAmazon] = DoLoadBitmap(hInst, "l", squareSize, "o");\r
+ pieceBitmap[2][WhiteAmazon] = 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][WhiteLion] = DoLoadBitmap(hInst, "ln", squareSize, "s");\r
+ pieceBitmap[1][WhiteLion] = DoLoadBitmap(hInst, "ln", squareSize, "o");\r
+ pieceBitmap[2][WhiteLion] = DoLoadBitmap(hInst, "ln", squareSize, "w");\r
+ pieceBitmap[0][WhiteCub] = DoLoadBitmap(hInst, "ln", squareSize, "s");\r
+ pieceBitmap[1][WhiteCub] = DoLoadBitmap(hInst, "ln", squareSize, "o");\r
+ pieceBitmap[2][WhiteCub] = DoLoadBitmap(hInst, "ln", squareSize, "w");\r
+ pieceBitmap[0][WhiteWolf] = DoLoadBitmap(hInst, "wolf", squareSize, "s");\r
+ pieceBitmap[1][WhiteWolf] = DoLoadBitmap(hInst, "wolf", squareSize, "o");\r
+ pieceBitmap[2][WhiteWolf] = DoLoadBitmap(hInst, "wolf", squareSize, "w");\r
+ pieceBitmap[0][WhiteCamel] = DoLoadBitmap(hInst, "camel", squareSize, "s");\r
+ pieceBitmap[1][WhiteCamel] = DoLoadBitmap(hInst, "camel", squareSize, "o");\r
+ pieceBitmap[2][WhiteCamel] = DoLoadBitmap(hInst, "camel", squareSize, "w");\r
+ pieceBitmap[0][WhiteZebra] = DoLoadBitmap(hInst, "zebra", squareSize, "s");\r
+ pieceBitmap[1][WhiteZebra] = DoLoadBitmap(hInst, "zebra", squareSize, "o");\r
+ pieceBitmap[2][WhiteZebra] = DoLoadBitmap(hInst, "n", squareSize, "w");\r
+\r
+ if(gameInfo.variant == VariantShogi && BOARD_HEIGHT != 7) { /* promoted Gold representations (but not in Tori!)*/\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[2][WhiteSilver] = DoLoadBitmap(hInst, "sw", squareSize, "w");\r
minorSize = 0;\r
}\r
+\r
+ if(appData.pieceDirectory[0]) for(i=WhitePawn; i<BlackPawn; i++) { // try for all missing pieces with new naming convention\r
+ char buf[MSG_SIZ];\r
+ if(pieceBitmap[0][i]) continue;\r
+ snprintf(buf, MSG_SIZ, "piece%d_", i);\r
+ pieceBitmap[0][i] = DoLoadBitmap(hInst, buf, squareSize, "s");\r
+ pieceBitmap[1][i] = DoLoadBitmap(hInst, buf, squareSize, "o");\r
+ pieceBitmap[2][i] = DoLoadBitmap(hInst, buf, squareSize, "w");\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_WIDTH-1)-column) * (squareSize + lineGap);\r
- *y = boardRect.top + lineGap + row * (squareSize + lineGap);\r
+ *x = boardRect.left + lineGap + ((BOARD_WIDTH-1)-column) * (squareSize + lineGap) + border;\r
+ *y = boardRect.top + lineGap + row * (squareSize + lineGap) + border;\r
} else {\r
- *x = boardRect.left + lineGap + column * (squareSize + lineGap);\r
- *y = boardRect.top + lineGap + ((BOARD_HEIGHT-1)-row) * (squareSize + lineGap);\r
+ *x = boardRect.left + lineGap + column * (squareSize + lineGap) + border;\r
+ *y = boardRect.top + lineGap + ((BOARD_HEIGHT-1)-row) * (squareSize + lineGap) + border;\r
}\r
}\r
\r
y = boardRect.top + lineGap;\r
x = boardRect.left + lineGap + gameInfo.holdingsWidth*(squareSize + lineGap);\r
\r
+ if(border) {\r
+ SetTextAlign(hdc, TA_RIGHT|TA_TOP);\r
+ x += border - lineGap - 4; y += squareSize - 6;\r
+ } else\r
SetTextAlign(hdc, TA_LEFT|TA_TOP);\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
+ ExtTextOut(hdc, x + 2 - (border ? gameInfo.holdingsWidth * (squareSize + lineGap) : 0), y + 1, 0, NULL, str, 1, NULL);\r
y += squareSize + lineGap;\r
}\r
\r
start = flipView ? 23-(BOARD_RGHT-BOARD_LEFT) : 23;\r
\r
+ if(border) {\r
+ SetTextAlign(hdc, TA_LEFT|TA_TOP);\r
+ x += -border + 4; y += border - squareSize + 6;\r
+ } else\r
SetTextAlign(hdc, TA_RIGHT|TA_BOTTOM);\r
for (i = 0; i < BOARD_RGHT - BOARD_LEFT; i++) {\r
str[0] = ranks[start + i];\r
if (lineGap == 0) return;\r
if (flipView) {\r
x1 = boardRect.left +\r
- lineGap/2 + ((BOARD_WIDTH-1)-x) * (squareSize + lineGap);\r
+ lineGap/2 + ((BOARD_WIDTH-1)-x) * (squareSize + lineGap) + border;\r
y1 = boardRect.top +\r
- lineGap/2 + y * (squareSize + lineGap);\r
+ lineGap/2 + y * (squareSize + lineGap) + border;\r
} else {\r
x1 = boardRect.left +\r
- lineGap/2 + x * (squareSize + lineGap);\r
+ lineGap/2 + x * (squareSize + lineGap) + border;\r
y1 = boardRect.top +\r
- lineGap/2 + ((BOARD_HEIGHT-1)-y) * (squareSize + lineGap);\r
+ lineGap/2 + ((BOARD_HEIGHT-1)-y) * (squareSize + lineGap) + border;\r
}\r
hPen = pen ? premovePen : highlightPen;\r
oldPen = SelectObject(hdc, on ? hPen : gridPen);\r
BitBlt(hdc, x, y, squareSize, squareSize, tmphdc, 0, 0,\r
sqcolor ? SRCCOPY : NOTSRCCOPY);\r
} else {\r
+ HBRUSH xBrush = whitePieceBrush;\r
tmpSize = squareSize;\r
+ if(appData.pieceDirectory[0]) xBrush = GetStockObject(WHITE_BRUSH);\r
if(minorSize &&\r
((piece >= (int)WhiteNightrider && piece <= WhiteGrasshopper) ||\r
(piece >= (int)BlackNightrider && piece <= BlackGrasshopper)) ) {\r
if (color || appData.allWhite ) {\r
oldBitmap = SelectObject(tmphdc, PieceBitmap(piece, WHITE_PIECE));\r
if( color )\r
- oldBrush = SelectObject(hdc, whitePieceBrush);\r
+ oldBrush = SelectObject(hdc, xBrush);\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
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
+ } else if(appData.pieceDirectory[0]) {\r
+ oldBitmap = SelectObject(tmphdc, PieceBitmap(piece, WHITE_PIECE));\r
+ oldBrush = SelectObject(hdc, xBrush);\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
+ SelectObject(tmphdc, PieceBitmap(piece, SOLID_PIECE));\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
} else {\r
/* Use square color for details of black pieces */\r
oldBitmap = SelectObject(tmphdc, PieceBitmap(piece, SOLID_PIECE));\r
}\r
\r
return result;\r
+\r
+\r
+\r
}\r
\r
BOOL IsDrawArrowEnabled()\r
return result;\r
}\r
\r
+static HBITMAP borderBitmap;\r
+\r
+VOID\r
+DrawBackgroundOnDC(HDC hdc)\r
+{\r
+ \r
+ BITMAP bi;\r
+ HDC tmphdc;\r
+ HBITMAP hbm;\r
+ static char oldBorder[MSG_SIZ];\r
+ int w = 600, h = 600, mode;\r
+\r
+ if(strcmp(appData.border, oldBorder)) { // load new one when old one no longer valid\r
+ strncpy(oldBorder, appData.border, MSG_SIZ-1);\r
+ borderBitmap = LoadImage( 0, appData.border, IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE ); \r
+ }\r
+ if(borderBitmap == NULL) { // loading failed, use white\r
+ FillRect( hdc, &boardRect, whitePieceBrush );\r
+ return;\r
+ }\r
+ tmphdc = CreateCompatibleDC(hdc);\r
+ hbm = SelectObject(tmphdc, borderBitmap);\r
+ if( GetObject( borderBitmap, sizeof(bi), &bi ) > 0 ) {\r
+ w = bi.bmWidth;\r
+ h = bi.bmHeight;\r
+ }\r
+ mode = SetStretchBltMode(hdc, COLORONCOLOR);\r
+ StretchBlt(hdc, boardRect.left, boardRect.top, boardRect.right - boardRect.left, \r
+ boardRect.bottom - boardRect.top, tmphdc, 0, 0, w, h, SRCCOPY);\r
+ SetStretchBltMode(hdc, mode);\r
+ SelectObject(tmphdc, hbm);\r
+ DeleteDC(tmphdc);\r
+}\r
+\r
VOID\r
DrawBoardOnDC(HDC hdc, Board board, HDC tmphdc)\r
{\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 if( piece == DarkSquare) DisplayHoldingsCount(hdc, x, y, 0, 0);\r
else\r
if (appData.monoMode) {\r
if (piece == EmptySquare) {\r
{\r
int square = color & 0x80;\r
HBRUSH oldBrush = SelectObject(hdcSeek, \r
- color == 0 ? markerBrush : color == 1 ? darkSquareBrush : explodeBrush);\r
+ color == 0 ? markerBrush[1] : color == 1 ? darkSquareBrush : explodeBrush);\r
color &= 0x7F;\r
if(square)\r
Rectangle(hdcSeek, boardRect.left+x - squareSize/9, boardRect.top+y - squareSize/9,\r
SelectObject(hdcSeek, oldBrush);\r
}\r
\r
+void DrawSeekOpen()\r
+{\r
+}\r
+\r
+void DrawSeekClose()\r
+{\r
+}\r
+\r
+\r
+\r
VOID\r
HDCDrawPosition(HDC hdc, BOOLEAN repaint, Board board)\r
{\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
+\r
lastDrawn[0][animInfo.to.y][animInfo.to.x] = animInfo.piece;\r
}\r
}\r
Ellipse(hdcmem, x-r, y-r, x+r, y+r);\r
SelectObject(hdcmem, oldBrush);\r
} else {\r
+ if(border) DrawBackgroundOnDC(hdcmem);\r
DrawGridOnDC(hdcmem);\r
if(nr == 0) { // [HGM] dual: decide which highlights to draw\r
DrawHighlightsOnDC(hdcmem, &highlightInfo, HIGHLIGHT_PEN);\r
for (row = 0; row < BOARD_HEIGHT; row++) {\r
for (column = 0; column < BOARD_WIDTH; column++) {\r
if (marker[row][column]) { // marker changes only occur with full repaint!\r
- HBRUSH oldBrush = SelectObject(hdcmem, \r
- marker[row][column] == 2 ? markerBrush : explodeBrush);\r
+ HBRUSH oldBrush = SelectObject(hdcmem, markerBrush[marker[row][column]-1]);\r
SquareToPos(row, column, &x, &y);\r
Ellipse(hdcmem, x + squareSize/4, y + squareSize/4,\r
x + 3*squareSize/4, y + 3*squareSize/4);\r
}\r
\r
if( appData.highlightMoveWithArrow ) {\r
+\r
DrawArrowHighlight(hdcmem);\r
}\r
\r
else\r
if(dragInfo.from.x == BOARD_RGHT+1 )\r
board[dragInfo.from.y][dragInfo.from.x-1]++;\r
+\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
if(saveDiagFlag) { \r
BITMAP b; int i, j=0, m, w, wb, fac=0; char *pData; \r
BITMAPINFOHEADER bih; int color[16], nrColors=0;\r
+ HBITMAP src = bufferBitmap, obmp; HDC tmp = CreateCompatibleDC(hdc);\r
\r
+ bufferBitmap = CreateCompatibleBitmap(hdc, boardRect.right-boardRect.left, Rect.bottom-Rect.top-2*OUTER_MARGIN);\r
+ obmp = SelectObject(tmp, bufferBitmap);\r
+ BitBlt(tmp, 0, 0, boardRect.right - boardRect.left, Rect.bottom - Rect.top - 2*OUTER_MARGIN,\r
+ tmphdc, boardRect.left, OUTER_MARGIN, SRCCOPY);\r
GetObject(bufferBitmap, sizeof(b), &b);\r
if(pData = malloc(b.bmWidthBytes*b.bmHeight + 10000)) {\r
bih.biSize = sizeof(BITMAPINFOHEADER);\r
fputc(pData[i], diagFile);\r
free(pData);\r
}\r
+ DeleteObject(bufferBitmap); bufferBitmap = src;\r
+ SelectObject(tmp, obmp);\r
+ DeleteDC(tmp);\r
}\r
\r
SelectObject(tmphdc, oldBitmap);\r
int EventToSquare(x, limit)\r
int x, limit;\r
{\r
- if (x <= 0)\r
+ if (x <= border)\r
return -2;\r
- if (x < lineGap)\r
+ if (x < lineGap + border)\r
return -1;\r
- x -= lineGap;\r
+ x -= lineGap + border;\r
if ((x % (squareSize + lineGap)) >= squareSize)\r
return -1;\r
x /= (squareSize + lineGap);\r
}\r
\r
shiftKey = GetKeyState(VK_SHIFT) < 0; // [HGM] remember last shift status\r
+ controlKey = GetKeyState(VK_CONTROL) < 0; // [HGM] remember last shift status\r
\r
switch (message) {\r
case WM_LBUTTONDOWN:\r
} else if (PtInRect((LPRECT) &blackRect, pt)) {\r
ClockClick(!flipClock); break;\r
}\r
+ if(dragging) { // [HGM] lion: don't destroy dragging info if we are already dragging\r
dragInfo.start.x = dragInfo.start.y = -1;\r
dragInfo.from = dragInfo.start;\r
+ }\r
if(fromX == -1 && frozen) { // not sure where this is for\r
fromX = fromY = -1; \r
DrawPosition(forceFullRepaint || FALSE, NULL); /* [AS] */\r
if(PromoScroll(pt.x - boardRect.left, pt.y - boardRect.top)) break;\r
MovePV(pt.x - boardRect.left, pt.y - boardRect.top, boardRect.bottom - boardRect.top);\r
if ((appData.animateDragging || appData.highlightDragging)\r
- && (wParam & MK_LBUTTON)\r
+ && (wParam & MK_LBUTTON || dragging == 2)\r
&& dragInfo.from.x >= 0) \r
{\r
BOOL full_repaint = FALSE;\r
dragInfo.pos = pt;\r
}\r
if (appData.highlightDragging) {\r
- SetHighlights(fromX, fromY, x, y);\r
+ HoverEvent(highlightInfo.sq[1].x, highlightInfo.sq[1].y, x, y);\r
if( IsDrawArrowEnabled() && (x < 0 || x >= BOARD_WIDTH || y < 0 || y >= BOARD_HEIGHT) ) {\r
full_repaint = TRUE;\r
}\r
return CallWindowProc(buttonDesc[i].wndproc, hwnd, message, wParam, lParam);\r
}\r
\r
+static int promoStyle;\r
+\r
/* Process messages for Promotion dialog box */\r
LRESULT CALLBACK\r
Promotion(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)\r
{\r
+\r
char promoChar;\r
\r
switch (message) {\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
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
- if(gameInfo.variant == VariantShogi) {\r
+ ShowWindow(GetDlgItem(hDlg, PB_Rook), !promoStyle ? SW_SHOW : SW_HIDE);\r
+ ShowWindow(GetDlgItem(hDlg, PB_Bishop), !promoStyle ? SW_SHOW : SW_HIDE);\r
+ if(promoStyle) {\r
SetDlgItemText(hDlg, PB_Queen, "YES");\r
SetDlgItemText(hDlg, PB_Knight, "NO");\r
SetWindowText(hDlg, "Promote?");\r
promoChar = gameInfo.variant == VariantSuper ? PieceToChar(BlackSilver) : PieceToChar(BlackKing);\r
break;\r
case PB_Queen:\r
- promoChar = gameInfo.variant == VariantShogi ? '+' : ToLower(PieceToChar(WhiteOnMove(currentMove) ? WhiteQueen : BlackQueen));\r
+ promoChar = promoStyle ? '+' : ToLower(PieceToChar(WhiteOnMove(currentMove) ? WhiteQueen : BlackQueen));\r
break;\r
case PB_Rook:\r
promoChar = ToLower(PieceToChar(WhiteOnMove(currentMove) ? WhiteRook : BlackRook));\r
promoChar = ToLower(PieceToChar(WhiteOnMove(currentMove) ? WhiteAngel : BlackAngel));\r
break;\r
case PB_Knight:\r
- promoChar = gameInfo.variant == VariantShogi ? '=' : PieceToChar(WhiteOnMove(currentMove) ? WhiteKnight : BlackKnight);\r
+ promoChar = gameInfo.variant == VariantShogi ? '=' : promoStyle ? NULLCHAR : \r
+ ToLower(PieceToChar(WhiteOnMove(currentMove) ? WhiteKnight : BlackKnight));\r
break;\r
default:\r
return FALSE;\r
}\r
\r
void\r
-PromotionPopUp()\r
+PromotionPopUp(char choice)\r
{\r
+ promoStyle = (choice == '+' || IS_SHOGI(gameInfo.variant));\r
DrawPosition(TRUE, NULL);\r
PromotionPopup(hwndMain);\r
}\r
\r
-/* Toggle ShowThinking */\r
-VOID\r
-ToggleShowThinking()\r
-{\r
- appData.showThinking = !appData.showThinking;\r
- ShowThinkingEvent();\r
-}\r
-\r
VOID\r
LoadGameDialog(HWND hwnd, char* title)\r
{\r
WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)\r
{\r
FARPROC lpProc;\r
- int wmId, wmEvent;\r
+ int wmId;\r
char *defName;\r
FILE *f;\r
UINT number;\r
char fileTitle[MSG_SIZ];\r
- char buf[MSG_SIZ];\r
static SnapData sd;\r
static int peek=0;\r
\r
nnew = RealizePalette(hdc);\r
if (nnew > 0) {\r
paletteChanged = TRUE;\r
+\r
InvalidateRect(hwnd, &boardRect, FALSE);\r
}\r
ReleaseDC(hwnd, hdc);\r
\r
case WM_COMMAND: /* message: command from application menu */\r
wmId = LOWORD(wParam);\r
- wmEvent = HIWORD(wParam);\r
\r
switch (wmId) {\r
case IDM_NewGame:\r
}\r
break;\r
\r
+ case IDM_SaveSelected:\r
+ f = OpenFileDialog(hwnd, "a", "",\r
+ "pgn",\r
+ GAME_FILT,\r
+ _("Save Game to File"), NULL, fileTitle, NULL);\r
+ if (f != NULL) {\r
+ SaveSelected(f, 0, "");\r
+ }\r
+ break;\r
+\r
+ case IDM_CreateBook:\r
+ CreateBookEvent();\r
+ break;\r
+\r
case IDM_CopyGame:\r
CopyGameToClipboard();\r
break;\r
break;\r
\r
case IDM_Match: // [HGM] match: flows into next case, after setting Match Mode and nr of Games\r
+ if(matchMode) EnableMenuItem(GetMenu(hwndMain), IDM_Match, MF_BYCOMMAND|MF_GRAYED);\r
MatchEvent(2); // distinguish from command-line-triggered case (matchMode=1)\r
break;\r
\r
case IDM_TwoMachines:\r
TwoMachinesEvent();\r
/*\r
+\r
* refresh the tags dialog only if it's visible\r
*/\r
if (gameMode == TwoMachinesPlay && IsWindowVisible(editTagsDialog)) {\r
break;\r
\r
case IDM_AnalysisMode:\r
- if (!first.analysisSupport) {\r
- snprintf(buf, MSG_SIZ, _("%s does not support analysis"), first.tidy);\r
- DisplayError(buf, 0);\r
- } else {\r
+ if(AnalyzeModeEvent()) {\r
SAY("analyzing current position");\r
- /* [DM] icsEngineAnlyze [HGM] Why is this front-end??? */\r
- if (appData.icsActive) {\r
- if (gameMode != IcsObserving) {\r
- snprintf(buf, MSG_SIZ, "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
case IDM_AnalyzeFile:\r
- if (!first.analysisSupport) {\r
- char buf[MSG_SIZ];\r
- snprintf(buf, MSG_SIZ, _("%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
- }\r
+ AnalyzeFileEvent();\r
break;\r
\r
case IDM_IcsClient:\r
EditTagsPopUp(firstChessProgramNames, &firstChessProgramNames);\r
break;\r
\r
- case IDM_EditProgs2:\r
- LoadEnginePopUp(hwndMain);\r
-// EditTagsPopUp(secondChessProgramNames, &secondChessProgramNames);\r
+ case IDM_LoadProg1:\r
+ LoadEnginePopUp(hwndMain, 0);\r
+ break;\r
+\r
+ case IDM_LoadProg2:\r
+ LoadEnginePopUp(hwndMain, 1);\r
break;\r
\r
case IDM_EditServers:\r
break;\r
\r
case IDM_Rematch:\r
+\r
RematchEvent();\r
break;\r
\r
BoardOptionsPopup(hwnd);\r
break;\r
\r
+ case IDM_ThemeOptions:\r
+ ThemeOptionsPopup(hwnd);\r
+ break;\r
+\r
case IDM_EnginePlayOptions:\r
EnginePlayOptionsPopup(hwnd);\r
break;\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
+ if( ((lpwp->flags & SWP_NOMOVE) == 0) /*&& ((lpwp->flags & SWP_NOSIZE) != 0)*/ ) { // [HGM] in Win8 size always accompanies move?\r
/* Window is moving */\r
RECT rcMain;\r
\r
ReattachAfterMove( &rcMain, lpwp->x, lpwp->y, hwndConsole, &wpConsole );\r
wpMain.x = lpwp->x;\r
wpMain.y = lpwp->y;\r
+\r
}\r
}\r
break;\r
default: /* Passes it on if unprocessed */\r
return (DefWindowProc(hwnd, message, wParam, lParam));\r
}\r
+\r
+\r
return 0;\r
}\r
\r
SwapEngines(singleList); // temporarily swap first and second, to load a second 'first', ...\r
ParseArgs(StringGet, &p);\r
SwapEngines(singleList); // ... and then make it 'second'\r
+\r
appData.noChessProgram = FALSE;\r
appData.icsActive = FALSE;\r
} else if (IsDlgButtonChecked(hDlg, OPT_ChessServer)) {\r
CommentDialog(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)\r
{\r
static HANDLE hwndText = NULL;\r
- int len, newSizeX, newSizeY, flags;\r
+ int len, newSizeX, newSizeY;\r
static int sizeX, sizeY;\r
char *str;\r
RECT rect;\r
/* Size and position the dialog */\r
if (!commentDialog) {\r
commentDialog = hDlg;\r
- flags = SWP_NOZORDER;\r
GetClientRect(hDlg, &rect);\r
sizeX = rect.right;\r
sizeY = rect.bottom;\r
case IDOK:\r
GetDlgItemText(hDlg, OPT_Name, move, sizeof(move));\r
appData.userName = strdup(move);\r
- SetUserLogo();\r
+ SetUserLogo(); DisplayLogos();\r
SetGameInfo();\r
if(gameMode == MachinePlaysWhite || gameMode == MachinePlaysBlack) {\r
snprintf(move, MSG_SIZ, "%s vs. %s", gameInfo.white, gameInfo.black);\r
LRESULT CALLBACK\r
ErrorDialog(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)\r
{\r
- HANDLE hwndText;\r
RECT rChild;\r
\r
switch (message) {\r
\r
errorDialog = hDlg;\r
SetWindowText(hDlg, errorTitle);\r
- hwndText = GetDlgItem(hDlg, OPT_ErrorText);\r
SetDlgItemText(hDlg, OPT_ErrorText, errorMessage);\r
return FALSE;\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
*/\r
gothicDialog = hDlg;\r
SetWindowText(hDlg, errorTitle);\r
- hwndText = GetDlgItem(hDlg, OPT_ErrorText);\r
SetDlgItemText(hDlg, OPT_ErrorText, errorMessage);\r
return FALSE;\r
\r
static char *history[HISTORY_SIZE];\r
int histIn = 0, histP = 0;\r
\r
+\r
VOID\r
SaveInHistory(char *cmd)\r
{\r
histIn = (histIn + 1) % HISTORY_SIZE;\r
if (history[histIn] != NULL) {\r
free(history[histIn]);\r
+\r
history[histIn] = NULL;\r
}\r
histP = histIn;\r
COLORREF oldFg, oldBg;\r
HFONT oldFont;\r
\r
+ if (twoBoards && partnerUp) return;\r
if (appData.clockMode) {\r
- if (tinyLayout)\r
+ if (tinyLayout == 2)\r
snprintf(buf, sizeof(buf)/sizeof(buf[0]), "%c %s %s", color[0], TimeString(timeRemaining), flagFell);\r
else\r
snprintf(buf, sizeof(buf)/sizeof(buf[0]), "%s:%c%s %s", color, (logoHeight>0 ? 0 : ' '), TimeString(timeRemaining), flagFell);\r
oldFg = SetTextColor(hdc, RGB(0, 0, 0)); /* black */\r
oldBg = SetBkColor(hdc, RGB(255, 255, 255)); /* white */\r
}\r
+\r
oldFont = SelectObject(hdc, font[boardSize][CLOCK_FONT]->hf);\r
\r
JAWS_SILENCE\r
else\r
err = GetLastError();\r
}\r
+\r
}\r
return err;\r
}\r
{ IDM_Annotate, MF_BYCOMMAND|MF_GRAYED },\r
{ IDM_NewChat, MF_BYCOMMAND|MF_GRAYED },\r
\r
+\r
// Needed to switch from ncp to GNU mode on Engine Load\r
{ ACTION_POS, MF_BYPOSITION|MF_ENABLED },\r
{ IDM_MachineWhite, MF_BYCOMMAND|MF_ENABLED },\r
{ IDM_MoveNow, MF_BYCOMMAND|MF_GRAYED },\r
{ IDM_Hint, MF_BYCOMMAND|MF_GRAYED },\r
{ IDM_Book, MF_BYCOMMAND|MF_GRAYED },\r
- { IDM_EditProgs2, MF_BYCOMMAND|MF_GRAYED },\r
+ { IDM_LoadProg1, MF_BYCOMMAND|MF_GRAYED },\r
+ { IDM_LoadProg2, MF_BYCOMMAND|MF_GRAYED },\r
{ IDM_IcsOptions, MF_BYCOMMAND|MF_ENABLED },\r
{ IDM_Engine1Options, MF_BYCOMMAND|MF_GRAYED },\r
{ IDM_Engine2Options, MF_BYCOMMAND|MF_GRAYED },\r
nowChecked = 0;\r
break;\r
}\r
+ if(prevChecked == IDM_TwoMachines) // [HGM] 'Machine Match' might have gotten disabled when stopping match\r
+ EnableMenuItem(GetMenu(hwndMain), IDM_Match, MF_BYCOMMAND|MF_ENABLED);\r
CheckMark(prevChecked, MF_UNCHECKED);\r
CheckMark(nowChecked, MF_CHECKED);\r
CheckMark(IDM_Match, matchMode && matchGame < appData.matchGames ? MF_CHECKED : MF_UNCHECKED);\r
fprintf(debugFP, "%s: %s\n", label, str);\r
}\r
if (appData.popupExitMessage) {\r
+ if(appData.icsActive) SendToICS("logout\n"); // [HGM] make sure no new games will be started!\r
(void) MessageBox(hwndMain, str, label, MB_OK|\r
(exitStatus ? MB_ICONSTOP : MB_ICONINFORMATION));\r
}\r
\r
// low-level front-end: clear text edit / list widget\r
void\r
+\r
GLT_ClearList()\r
{\r
SendDlgItemMessage( gameListOptionsDialog, IDC_GameListTags, LB_RESETCONTENT, 0, 0 );\r
result = DialogBoxParam( hInst, MAKEINTRESOURCE(DLG_GameListOptions), hwndMain, (DLGPROC)lpProc, (LPARAM)lpUserGLT );\r
\r
if( result == 0 ) {\r
+ char *oldTags = appData.gameListTags;\r
/* [AS] Memory leak here! */\r
appData.gameListTags = strdup( lpUserGLT ); \r
+ if(strcmp(oldTags, appData.gameListTags)) // [HGM] redo Game List when we changed something\r
+ GameListToListBox(NULL, TRUE, ".", NULL, FALSE, FALSE); // "." as filter is kludge to select all\r
}\r
\r
return result;\r
}\r
\r
\r
+int\r
+Roar()\r
+{\r
+ MyPlaySound(&sounds[(int)SoundRoar]);\r
+ return 1;\r
+}\r
+\r
VOID\r
RingBell()\r
{\r
HDC hdc;\r
char *flag = blackFlag && gameMode == TwoMachinesPlay ? "(!)" : "";\r
\r
+\r
if(appData.noGUI) return;\r
hdc = GetDC(hwndMain);\r
if (!IsIconic(hwndMain)) {\r
*/\r
if (nice < -15) return 0x00000080;\r
if (nice < 0) return 0x00008000;\r
+\r
if (nice == 0) return 0x00000020;\r
if (nice < 15) return 0x00004000;\r
return 0x00000040;\r
/*!!if (signal) GenerateConsoleCtrlEvent(CTRL_BREAK_EVENT, cp->pid);*/\r
\r
/* [AS] Special termination modes for misbehaving programs... */\r
- if( signal == 9 ) { \r
+ if( signal & 8 ) { \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
+ else if( signal & 4 ) {\r
+ DWORD dw = WaitForSingleObject( cp->hProcess, appData.delayAfterQuit*1000 + 50 ); // Wait 3 seconds at most\r
\r
if( dw != WAIT_OBJECT_0 ) {\r
result = TerminateProcess( cp->hProcess, 0 );\r
ChildProc *cp;\r
int err;\r
SOCKET s;\r
+\r
struct sockaddr_in sa, mysa;\r
struct hostent FAR *hp;\r
unsigned short uport;\r
int outCount = SOCKET_ERROR;\r
ChildProc *cp = (ChildProc *) pr;\r
static OVERLAPPED ovl;\r
+\r
static int line = 0;\r
\r
if (pr == NoProc)\r
/* see wedittags.c for Edit Tags functions */\r
\r
\r
-VOID\r
+int\r
ICSInitScript()\r
{\r
FILE *f;\r
if (f != NULL) {\r
ProcessICSInitScript(f);\r
fclose(f);\r
+ return TRUE;\r
}\r
}\r
+ return FALSE;\r
}\r
\r
\r
int toX;\r
int toY;\r
{\r
- ChessSquare piece;\r
+ ChessSquare piece, victim = EmptySquare, victim2 = EmptySquare;\r
+ int x = toX, y = toY, x2 = kill2X;\r
POINT start, finish, mid;\r
POINT frames[kFactor * 2 + 1];\r
int nFrames, n;\r
\r
+ if(killX >= 0 && IS_LION(board[fromY][fromX])) Roar();\r
+\r
if (!appData.animate) return;\r
if (doingSizing) return;\r
if (fromY < 0 || fromX < 0) return;\r
piece = board[fromY][fromX];\r
if (piece >= EmptySquare) return;\r
\r
+ if(x2 >= 0) toX = kill2X, toY = kill2Y, victim = board[killY][killX], victim2 = board[kill2Y][kill2X]; else\r
+ if(killX >= 0) toX = killX, toY = killY, victim = board[killY][killX]; // [HGM] lion: first to kill square\r
+\r
+ animInfo.from.x = fromX;\r
+ animInfo.from.y = fromY;\r
+\r
+again:\r
+\r
ScreenSquare(fromX, fromY, &start);\r
ScreenSquare(toX, toY, &finish);\r
\r
else\r
Tween(&start, &mid, &finish, kFactor, frames, &nFrames);\r
\r
- animInfo.from.x = fromX;\r
- animInfo.from.y = fromY;\r
animInfo.to.x = toX;\r
animInfo.to.y = toY;\r
animInfo.lastpos = start;\r
animInfo.piece = piece;\r
for (n = 0; n < nFrames; n++) {\r
animInfo.pos = frames[n];\r
- DrawPosition(FALSE, NULL);\r
+ DrawPosition(FALSE, board);\r
animInfo.lastpos = animInfo.pos;\r
Sleep(appData.animSpeed);\r
}\r
animInfo.pos = finish;\r
- DrawPosition(FALSE, NULL);\r
+ DrawPosition(FALSE, board);\r
+\r
+ if(toX == x2 && toY == kill2Y) {\r
+ fromX = toX; fromY = toY; toX = killX; toY = killY; x2 = -1;\r
+ board[kill2Y][kill2X] = EmptySquare; goto again;\r
+ } // second leg\r
+ if(toX != x || toY != y) {\r
+ fromX = toX; fromY = toY; toX = x; toY = y;\r
+ board[killY][killX] = EmptySquare; goto again;\r
+ } // second leg\r
+\r
+if(victim2 != EmptySquare) board[kill2Y][kill2X] = victim2;\r
+if(victim != EmptySquare) board[killY][killX] = victim;\r
+\r
animInfo.piece = EmptySquare;\r
Explode(board, fromX, fromY, toX, toY);\r
}\r
int column; int row; POINT * pt;\r
{\r
if (flipView) {\r
- pt->x = lineGap + ((BOARD_WIDTH-1)-column) * (squareSize + lineGap);\r
- pt->y = lineGap + row * (squareSize + lineGap);\r
+ pt->x = lineGap + ((BOARD_WIDTH-1)-column) * (squareSize + lineGap) + border;\r
+ pt->y = lineGap + row * (squareSize + lineGap) + border;\r
} else {\r
- pt->x = lineGap + column * (squareSize + lineGap);\r
- pt->y = lineGap + ((BOARD_HEIGHT-1)-row) * (squareSize + lineGap);\r
+ pt->x = lineGap + column * (squareSize + lineGap) + border;\r
+ pt->y = lineGap + ((BOARD_HEIGHT-1)-row) * (squareSize + lineGap) + border;\r
}\r
}\r
\r
ov.OffsetHigh = 0;\r
switch(code) {\r
case 1: LockFileEx(hFile, LOCKFILE_EXCLUSIVE_LOCK, 0, 1024, 0, &ov); break; // LOCK_SH\r
+\r
case 2: LockFileEx(hFile, LOCKFILE_EXCLUSIVE_LOCK, 0, 1024, 0, &ov); break; // LOCK_EX\r
case 3: UnlockFileEx(hFile, 0, 1024, 0, &ov); break; // LOCK_UN\r
default: return -1;\r
}\r
return 0;\r
}\r
+\r
+char *\r
+Col2Text (int n)\r
+{\r
+ static int i=0;\r
+ static char col[8][20];\r
+ COLORREF color = *(COLORREF *) colorVariable[n];\r
+ i = i+1 & 7;\r
+ snprintf(col[i], 20, "#%02lx%02lx%02lx", color&0xff, (color>>8)&0xff, (color>>16)&0xff);\r
+ return col[i];\r
+}\r
+\r
+void\r
+ActivateTheme (int new)\r
+{ // Redo initialization of features depending on options that can occur in themes\r
+ InitTextures();\r
+ if(new) InitDrawingColors();\r
+ fontBitmapSquareSize = 0; // request creation of new font pieces\r
+ InitDrawingSizes(boardSize, 0);\r
+ InvalidateRect(hwndMain, NULL, TRUE);\r
+}\r