X-Git-Url: http://winboard.nl/cgi-bin?a=blobdiff_plain;f=winboard%2Fwinboard.c;h=917a532a1ea842a5a34c2abb585b5c0c9c2c6a8d;hb=35f89898c92a8709618e2db77b11cbedfd7fc48c;hp=361695702ae3f25e1574a957750b781b18e9000f;hpb=5f63467b1d95796ea9051335b14f074bf9485b21;p=xboard.git diff --git a/winboard/winboard.c b/winboard/winboard.c index 3616957..917a532 100644 --- a/winboard/winboard.c +++ b/winboard/winboard.c @@ -5,7 +5,7 @@ * Massachusetts. * * Enhancements Copyright 1992-2001, 2002, 2003, 2004, 2005, 2006, - * 2007, 2008, 2009, 2010, 2011, 2012 Free Software Foundation, Inc. + * 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc. * * Enhancements Copyright 2005 Alessandro Scotti * @@ -92,6 +92,9 @@ #include "help.h" #include "wsnap.h" +#define SLASH '/' +#define DATADIR "~~" + //void InitEngineUCI( const char * iniDir, ChessProgramState * cps ); int myrandom(void); @@ -109,7 +112,6 @@ VOID NewVariantPopup(HWND hwnd); int FinishMove P((ChessMove moveType, int fromX, int fromY, int toX, int toY, /*char*/int promoChar)); void DisplayMove P((int moveNumber)); -Boolean ParseFEN P((Board board, int *blackPlaysFirst, char *fen)); void ChatPopUp P((char *s)); typedef struct { ChessSquare piece; @@ -187,6 +189,7 @@ Boolean alwaysOnTop = FALSE; RECT boardRect; COLORREF lightSquareColor, darkSquareColor, whitePieceColor, blackPieceColor, highlightSquareColor, premoveHighlightColor; +COLORREF markerColor[8] = { 0x00FFFF, 0x0000FF, 0x00FF00, 0xFF0000, 0xFFFF00, 0xFF00FF, 0xFFFFFF, 0x000000 }; HPALETTE hPal; ColorClass currentColorClass; @@ -197,7 +200,7 @@ static HBITMAP pieceBitmap[3][(int) BlackPawn]; /* [HGM] nr of bitmaps referred static HBRUSH lightSquareBrush, darkSquareBrush, blackSquareBrush, /* [HGM] for band between board and holdings */ explodeBrush, /* [HGM] atomic */ - markerBrush, /* [HGM] markers */ + markerBrush[8], /* [HGM] markers */ whitePieceBrush, blackPieceBrush, iconBkgndBrush /*, outlineBrush*/; static POINT gridEndpoints[(BOARD_RANKS + BOARD_FILES + 2) * 2]; static DWORD gridVertexCounts[BOARD_RANKS + BOARD_FILES + 2]; @@ -222,6 +225,7 @@ static struct { int x; int y; int mode; } backTextureSquareInfo[BOARD_RANKS][BOA #if __GNUC__ && !defined(_winmajor) #define oldDialog 0 /* cygwin doesn't define _winmajor; mingw does */ #else + #if defined(_winmajor) #define oldDialog (_winmajor < 4) #else @@ -296,7 +300,7 @@ int dialogItems[][42] = { OPT_ChooseTellColor, OPT_ChooseChallengeColor, OPT_ChooseRequestColor, OPT_ChooseSeekColor, OPT_ChooseNormalColor, OPT_ChooseBackgroundColor, OPT_DefaultColors, OPT_DontColorize, IDC_Boxes, GPB_Colors, GPB_Premove, - GPB_General, GPB_Alarm }, + GPB_General, GPB_Alarm, OPT_AutoCreate }, { DLG_BoardOptions, IDOK, IDCANCEL, OPT_SizeTiny, OPT_SizeTeeny, OPT_SizeDinky, OPT_SizePetite, OPT_SizeSlim, OPT_SizeSmall, OPT_SizeMediocre, OPT_SizeMiddling, OPT_SizeAverage, OPT_SizeModerate, OPT_SizeMedium, OPT_SizeBulky, OPT_SizeLarge, @@ -1063,6 +1067,7 @@ InitInstance(HINSTANCE hInstance, int nCmdShow, LPSTR lpCmdLine) if (SearchPath(NULL, "WinBoard.exe", NULL, MSG_SIZ, installDir, &filepart)) { *filepart = NULLCHAR; + SetCurrentDirectory(installDir); } else { GetCurrentDirectory(MSG_SIZ, installDir); } @@ -1116,6 +1121,7 @@ InitInstance(HINSTANCE hInstance, int nCmdShow, LPSTR lpCmdLine) InitDrawingColors(); screenHeight = GetSystemMetrics(SM_CYSCREEN); screenWidth = GetSystemMetrics(SM_CXSCREEN); + InitPosition(0); // to set nr of ranks and files, which might be non-default through command-line args for (ibs = (int) NUM_SIZES - 1; ibs >= 0; ibs--) { /* Compute window size for each board size, and use the largest size that fits on this screen as the default. */ @@ -1279,6 +1285,7 @@ ParseFontName(char *name, MyFontParams *mfp) p = q + 1; } else { q = mfp->faceName; + while (*p && !isdigit(*p)) { *q++ = *p++; if (q - mfp->faceName >= sizeof(mfp->faceName)) @@ -2160,6 +2167,7 @@ InsertInPalette(COLORREF color) VOID InitDrawingColors() { + int i; if (pLogPal == NULL) { /* Allocate enough memory for a logical palette with * PALETTESIZE entries and set the size and version fields @@ -2191,8 +2199,9 @@ InitDrawingColors() blackPieceBrush = CreateSolidBrush(blackPieceColor); iconBkgndBrush = CreateSolidBrush(GetSysColor(COLOR_BACKGROUND)); explodeBrush = CreateSolidBrush(highlightSquareColor); // [HGM] atomic - markerBrush = CreateSolidBrush(premoveHighlightColor); // [HGM] markers - /* [AS] Force rendering of the font-based pieces */ + for(i=0; i<8;i++) markerBrush[i] = CreateSolidBrush(markerColor[i]); // [HGM] markers + + /* [AS] Force rendering of the font-based pieces */ if( fontBitmapSquareSize > 0 ) { fontBitmapSquareSize = 0; } @@ -2257,6 +2266,7 @@ InitDrawingSizes(BoardSize boardSize, int flags) /* [HGM] call with -2 uses old size (for if nr of files, ranks changes) */ if(boardSize == (BoardSize)(-2) ) boardSize = oldBoardSize; + if(boardSize == -1) return; // no size defined yet; abort (to allow early call of InitPosition) oldBoardSize = boardSize; if(boardSize != SizeMiddling && boardSize != SizePetite && boardSize != SizeBulky && !appData.useFont) @@ -2265,13 +2275,13 @@ InitDrawingSizes(BoardSize boardSize, int flags) && (boardSize < SizePetite || boardSize > SizeBulky) // Archbishop and Chancellor available in entire middle range || (v == VariantShogi && boardSize != SizeModerate) // Japanese-style Shogi || v == VariantKnightmate || v == VariantSChess || v == VariantXiangqi || v == VariantSpartan - || v == VariantShatranj || v == VariantMakruk || v == VariantGreat || v == VariantFairy ) { + || v == VariantShatranj || v == VariantMakruk || v == VariantGreat || v == VariantFairy || v == VariantLion ) { if(boardSize < SizeMediocre) boardSize = SizePetite; else if(boardSize > SizeModerate) boardSize = SizeBulky; else boardSize = SizeMiddling; } } - if(!appData.useFont && boardSize == SizePetite && (v == VariantShogi || v == VariantKnightmate)) boardSize = SizeMiddling; // no Unicorn in Petite + if(!appData.useFont && boardSize == SizePetite && (v == VariantKnightmate)) boardSize = SizeMiddling; // no Unicorn in Petite oldRect.left = wpMain.x; //[HGM] placement: remember previous window params oldRect.top = wpMain.y; @@ -2621,6 +2631,9 @@ InitDrawingSizes(BoardSize boardSize, int flags) pieceBitmap[0][WhiteUnicorn] = DoLoadBitmap(hInst, "u", squareSize, "s"); pieceBitmap[1][WhiteUnicorn] = DoLoadBitmap(hInst, "u", squareSize, "o"); pieceBitmap[2][WhiteUnicorn] = DoLoadBitmap(hInst, "u", squareSize, "w"); + pieceBitmap[0][WhiteLion] = DoLoadBitmap(hInst, "ln", squareSize, "s"); + pieceBitmap[1][WhiteLion] = DoLoadBitmap(hInst, "ln", squareSize, "o"); + pieceBitmap[2][WhiteLion] = DoLoadBitmap(hInst, "ln", squareSize, "w"); if(gameInfo.variant == VariantShogi) { /* promoted Gold represemtations */ pieceBitmap[0][WhiteCannon] = DoLoadBitmap(hInst, "wp", squareSize, "s"); @@ -3242,6 +3255,9 @@ BOOL HasHighlightInfo() } return result; + + + } BOOL IsDrawArrowEnabled() @@ -3433,6 +3449,7 @@ DrawBoardOnDC(HDC hdc, Board board, HDC tmphdc) DisplayHoldingsCount(hdc, x, y, flipView, (int) board[row][column]); else if( column == BOARD_RGHT) /* right align */ DisplayHoldingsCount(hdc, x, y, !flipView, (int) board[row][column]); + else if( piece == DarkSquare) DisplayHoldingsCount(hdc, x, y, 0, 0); else if (appData.monoMode) { if (piece == EmptySquare) { @@ -3615,7 +3632,7 @@ void DrawSeekDot(int x, int y, int color) { int square = color & 0x80; HBRUSH oldBrush = SelectObject(hdcSeek, - color == 0 ? markerBrush : color == 1 ? darkSquareBrush : explodeBrush); + color == 0 ? markerBrush[1] : color == 1 ? darkSquareBrush : explodeBrush); color &= 0x7F; if(square) Rectangle(hdcSeek, boardRect.left+x - squareSize/9, boardRect.top+y - squareSize/9, @@ -3908,8 +3925,7 @@ HDCDrawPosition(HDC hdc, BOOLEAN repaint, Board board) for (row = 0; row < BOARD_HEIGHT; row++) { for (column = 0; column < BOARD_WIDTH; column++) { if (marker[row][column]) { // marker changes only occur with full repaint! - HBRUSH oldBrush = SelectObject(hdcmem, - marker[row][column] == 2 ? markerBrush : explodeBrush); + HBRUSH oldBrush = SelectObject(hdcmem, markerBrush[marker[row][column]-1]); SquareToPos(row, column, &x, &y); Ellipse(hdcmem, x + squareSize/4, y + squareSize/4, x + 3*squareSize/4, y + 3*squareSize/4); @@ -4256,6 +4272,7 @@ MouseEvent(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) } shiftKey = GetKeyState(VK_SHIFT) < 0; // [HGM] remember last shift status + controlKey = GetKeyState(VK_CONTROL) < 0; // [HGM] remember last shift status switch (message) { case WM_LBUTTONDOWN: @@ -4264,8 +4281,10 @@ MouseEvent(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) } else if (PtInRect((LPRECT) &blackRect, pt)) { ClockClick(!flipClock); break; } + if(dragging) { // [HGM] lion: don't destroy dragging info if we are already dragging dragInfo.start.x = dragInfo.start.y = -1; dragInfo.from = dragInfo.start; + } if(fromX == -1 && frozen) { // not sure where this is for fromX = fromY = -1; DrawPosition(forceFullRepaint || FALSE, NULL); /* [AS] */ @@ -4285,7 +4304,7 @@ MouseEvent(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) if(PromoScroll(pt.x - boardRect.left, pt.y - boardRect.top)) break; MovePV(pt.x - boardRect.left, pt.y - boardRect.top, boardRect.bottom - boardRect.top); if ((appData.animateDragging || appData.highlightDragging) - && (wParam & MK_LBUTTON) + && (wParam & MK_LBUTTON || dragging == 2) && dragInfo.from.x >= 0) { BOOL full_repaint = FALSE; @@ -4294,7 +4313,7 @@ MouseEvent(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) dragInfo.pos = pt; } if (appData.highlightDragging) { - SetHighlights(fromX, fromY, x, y); + HoverEvent(highlightInfo.sq[1].x, highlightInfo.sq[1].y, x, y); if( IsDrawArrowEnabled() && (x < 0 || x >= BOARD_WIDTH || y < 0 || y >= BOARD_HEIGHT) ) { full_repaint = TRUE; } @@ -4429,6 +4448,8 @@ ButtonProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) return CallWindowProc(buttonDesc[i].wndproc, hwnd, message, wParam, lParam); } +static int promoStyle; + /* Process messages for Promotion dialog box */ LRESULT CALLBACK Promotion(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) @@ -4459,13 +4480,9 @@ Promotion(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) PieceToChar(BlackMarshall) != '~') ) ? SW_SHOW : SW_HIDE); /* [HGM] Hide B & R button in Shogi, use Q as promote, N as defer */ - ShowWindow(GetDlgItem(hDlg, PB_Rook), - gameInfo.variant != VariantShogi ? - SW_SHOW : SW_HIDE); - ShowWindow(GetDlgItem(hDlg, PB_Bishop), - gameInfo.variant != VariantShogi ? - SW_SHOW : SW_HIDE); - if(gameInfo.variant == VariantShogi) { + ShowWindow(GetDlgItem(hDlg, PB_Rook), !promoStyle ? SW_SHOW : SW_HIDE); + ShowWindow(GetDlgItem(hDlg, PB_Bishop), !promoStyle ? SW_SHOW : SW_HIDE); + if(promoStyle) { SetDlgItemText(hDlg, PB_Queen, "YES"); SetDlgItemText(hDlg, PB_Knight, "NO"); SetWindowText(hDlg, "Promote?"); @@ -4486,7 +4503,7 @@ Promotion(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) promoChar = gameInfo.variant == VariantSuper ? PieceToChar(BlackSilver) : PieceToChar(BlackKing); break; case PB_Queen: - promoChar = gameInfo.variant == VariantShogi ? '+' : ToLower(PieceToChar(WhiteOnMove(currentMove) ? WhiteQueen : BlackQueen)); + promoChar = promoStyle ? '+' : ToLower(PieceToChar(WhiteOnMove(currentMove) ? WhiteQueen : BlackQueen)); break; case PB_Rook: promoChar = ToLower(PieceToChar(WhiteOnMove(currentMove) ? WhiteRook : BlackRook)); @@ -4503,7 +4520,8 @@ Promotion(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) promoChar = ToLower(PieceToChar(WhiteOnMove(currentMove) ? WhiteAngel : BlackAngel)); break; case PB_Knight: - promoChar = gameInfo.variant == VariantShogi ? '=' : PieceToChar(WhiteOnMove(currentMove) ? WhiteKnight : BlackKnight); + promoChar = gameInfo.variant == VariantShogi ? '=' : promoStyle ? NULLCHAR : + ToLower(PieceToChar(WhiteOnMove(currentMove) ? WhiteKnight : BlackKnight)); break; default: return FALSE; @@ -4534,8 +4552,9 @@ PromotionPopup(HWND hwnd) } void -PromotionPopUp() +PromotionPopUp(char choice) { + promoStyle = (choice == '+'); DrawPosition(TRUE, NULL); PromotionPopup(hwndMain); } @@ -4678,7 +4697,6 @@ WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) FILE *f; UINT number; char fileTitle[MSG_SIZ]; - char buf[MSG_SIZ]; static SnapData sd; static int peek=0; @@ -4753,6 +4771,7 @@ WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) nnew = RealizePalette(hdc); if (nnew > 0) { paletteChanged = TRUE; + InvalidateRect(hwnd, &boardRect, FALSE); } ReleaseDC(hwnd, hdc); @@ -5095,6 +5114,7 @@ WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) break; case IDM_Rematch: + RematchEvent(); break; @@ -6252,6 +6272,7 @@ StartupDialog(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) SwapEngines(singleList); // temporarily swap first and second, to load a second 'first', ... ParseArgs(StringGet, &p); SwapEngines(singleList); // ... and then make it 'second' + appData.noChessProgram = FALSE; appData.icsActive = FALSE; } else if (IsDlgButtonChecked(hDlg, OPT_ChessServer)) { @@ -6829,6 +6850,7 @@ GothicPopUp(char *title, VariantClass variant) static char *history[HISTORY_SIZE]; int histIn = 0, histP = 0; + VOID SaveInHistory(char *cmd) { @@ -6841,6 +6863,7 @@ SaveInHistory(char *cmd) histIn = (histIn + 1) % HISTORY_SIZE; if (history[histIn] != NULL) { free(history[histIn]); + history[histIn] = NULL; } histP = histIn; @@ -7651,6 +7674,7 @@ DoWriteFile(HANDLE hFile, char *buf, int count, DWORD *outCount, else err = GetLastError(); } + } return err; } @@ -8516,6 +8540,7 @@ HWND gameListOptionsDialog; // low-level front-end: clear text edit / list widget void + GLT_ClearList() { SendDlgItemMessage( gameListOptionsDialog, IDC_GameListTags, LB_RESETCONTENT, 0, 0 ); @@ -8707,6 +8732,13 @@ EditCommentPopUp(int index, char *title, char *str) } +int +Roar() +{ + MyPlaySound(&sounds[(int)SoundRoar]); + return 1; +} + VOID RingBell() { @@ -8864,6 +8896,7 @@ DisplayBlackClock(long timeRemaining, int highlight) HDC hdc; char *flag = blackFlag && gameMode == TwoMachinesPlay ? "(!)" : ""; + if(appData.noGUI) return; hdc = GetDC(hwndMain); if (!IsIconic(hwndMain)) { @@ -9882,16 +9915,23 @@ AnimateMove(board, fromX, fromY, toX, toY) int toY; { ChessSquare piece; + int x = toX, y = toY; POINT start, finish, mid; POINT frames[kFactor * 2 + 1]; int nFrames, n; + if(killX >= 0 && IS_LION(board[fromY][fromX])) Roar(); + if (!appData.animate) return; if (doingSizing) return; if (fromY < 0 || fromX < 0) return; piece = board[fromY][fromX]; if (piece >= EmptySquare) return; + if(killX >= 0) toX = killX, toY = killY; // [HGM] lion: first to kill square + +again: + ScreenSquare(fromX, fromY, &start); ScreenSquare(toX, toY, &finish); @@ -9930,6 +9970,9 @@ AnimateMove(board, fromX, fromY, toX, toY) } animInfo.pos = finish; DrawPosition(FALSE, NULL); + + if(toX != x || toY != y) { fromX = toX; fromY = toY; toX = x; toY = y; goto again; } // second leg + animInfo.piece = EmptySquare; Explode(board, fromX, fromY, toX, toY); } @@ -10031,6 +10074,6 @@ ActivateTheme (int new) InitTextures(); if(new) InitDrawingColors(); fontBitmapSquareSize = 0; // request creation of new font pieces - InitDrawingSizes(-2, 0); + InitDrawingSizes(boardSize, 0); InvalidateRect(hwndMain, NULL, TRUE); }