X-Git-Url: http://winboard.nl/cgi-bin?a=blobdiff_plain;f=winboard%2Fwinboard.c;h=f27a1e64e209cfa574ce2847fd5278b47d398b6b;hb=b382d988c6f886f3a49483df9e3e36de0b6b0824;hp=e92a265c67df5b3cb2feb61a8cf1365f2f220a0f;hpb=7c6f1f89aa5e21460c61dcc875ebc4cc3916455e;p=xboard.git diff --git a/winboard/winboard.c b/winboard/winboard.c index e92a265..f27a1e6 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 Free Software Foundation, Inc. + * 2007, 2008, 2009, 2010, 2011 Free Software Foundation, Inc. * * Enhancements Copyright 2005 Alessandro Scotti * @@ -105,7 +105,6 @@ void DisplayHoldingsCount(HDC hdc, int x, int y, int align, int copyNumber); VOID NewVariantPopup(HWND hwnd); int FinishMove P((ChessMove moveType, int fromX, int fromY, int toX, int toY, /*char*/int promoChar)); -void AnimateAtomicCapture(int fromX, int fromY, int toX, int toY, int nFrames); void DisplayMove P((int moveNumber)); Boolean ParseFEN P((Board board, int *blackPlaysFirst, char *fen)); void ChatPopUp P((char *s)); @@ -187,6 +186,7 @@ COLORREF lightSquareColor, darkSquareColor, whitePieceColor, HPALETTE hPal; ColorClass currentColorClass; +static HWND savedHwnd; HWND hCommPort = NULL; /* currently open comm port */ static HWND hwndPause; /* pause button */ static HBITMAP pieceBitmap[3][(int) BlackPawn]; /* [HGM] nr of bitmaps referred to bP in stead of wK */ @@ -248,7 +248,7 @@ Boolean barbaric; // flag indicating if translation is needed #define ABOUTBOX2 -1 int dialogItems[][40] = { -{ ABOUTBOX, IDOK, 400 }, +{ ABOUTBOX, IDOK, OPT_MESS, 400 }, { DLG_TimeControl, IDC_Babble, OPT_TCUseMoves, OPT_TCUseInc, OPT_TCUseFixed, OPT_TCtext1, OPT_TCtext2, OPT_TCitext1, OPT_TCitext2, OPT_TCftext, GPB_Factors, IDC_Factor1, IDC_Factor2, IDOK, IDCANCEL }, { DLG_LoadOptions, OPT_Autostep, OPT_AStext1, IDOK, IDCANCEL }, @@ -282,7 +282,7 @@ int dialogItems[][40] = { OPT_AutoFlipView, OPT_ShowButtonBar, OPT_AutoRaiseBoard, OPT_ShowCoordinates, OPT_Blindfold, OPT_ShowThinking, OPT_HighlightDragging, OPT_TestLegality, OPT_SaveExtPGN, OPT_HideThinkFromHuman, OPT_ExtraInfoInMoveHistory, - OPT_HighlightMoveArrow, OPT_AutoLogo }, + OPT_HighlightMoveArrow, OPT_AutoLogo ,OPT_SmartMove }, { DLG_IcsOptions, IDOK, IDCANCEL, OPT_AutoComment, OPT_AutoKibitz, OPT_AutoObserve, OPT_GetMoveList, OPT_LocalLineEditing, OPT_QuietPlay, OPT_SeekGraph, OPT_AutoRefresh, OPT_BgObserve, OPT_DualBoard, OPT_Premove, OPT_PremoveWhite, OPT_PremoveBlack, @@ -306,7 +306,7 @@ int dialogItems[][40] = { OPT_VariantBughouse, OPT_VariantTwilight, OPT_VariantShogi, OPT_VariantSuper, OPT_VariantKnightmate, OPT_VariantBerolina, OPT_VariantCylinder, OPT_VariantFairy, OPT_VariantMakruk, OPT_VariantGothic, OPT_VariantCapablanca, OPT_VariantJanus, - OPT_VariantCRC, OPT_VariantFalcon, OPT_VariantCourier, OPT_VariantGreat, + OPT_VariantCRC, OPT_VariantFalcon, OPT_VariantCourier, OPT_VariantGreat, OPT_VariantSChess, OPT_VariantShatranj, OPT_VariantXiangqi, GPB_Variant, GPB_Board, IDC_Height, IDC_Width, IDC_Hand, IDC_Pieces, IDC_Def }, { DLG_Fonts, IDOK, IDCANCEL, OPT_ChooseClockFont, OPT_ChooseMessageFont, @@ -334,7 +334,7 @@ static char languageBuf[50000], *foreign[1000], *english[1000], *languageFile[MS static int lastChecked; static char oldLanguage[MSG_SIZ], *menuText[10][30]; extern int tinyLayout; -extern char * menuBarText[][8]; +extern char * menuBarText[][10]; void LoadLanguageFile(char *name) @@ -383,7 +383,7 @@ T_(char *s) { // return the translation of the given string // efficiency can be improved a lot... int i=0; -if(appData.debugMode) fprintf(debugFP, "T_(%s)\n", s); +//if(appData.debugMode) fprintf(debugFP, "T_(%s)\n", s); if(!barbaric) return s; if(!s) return ""; // sanity while(english[i]) { @@ -398,13 +398,11 @@ Translate(HWND hDlg, int dialogID) { // translate all text items in the given dialog int i=0, j, k; char buf[MSG_SIZ], *s; -//if(appData.debugMode) fprintf(debugFP, "Translate(%d)\n", dialogID); if(!barbaric) return; while(dialogItems[i][0] && dialogItems[i][0] != dialogID) i++; // find the dialog description if(dialogItems[i][0] != dialogID) return; // unknown dialog, should not happen GetWindowText( hDlg, buf, MSG_SIZ ); s = T_(buf); -if(appData.debugMode) fprintf(debugFP, "WindowText '%s' -> '%s'\n", buf, s); if(strcmp(buf, s)) SetWindowText(hDlg, s); // replace by translated string (if different) for(j=1; k=dialogItems[i][j]; j++) { // translate all listed dialog items GetDlgItemText(hDlg, k, buf, MSG_SIZ); @@ -414,10 +412,35 @@ if(appData.debugMode) fprintf(debugFP, "WindowText '%s' -> '%s'\n", buf, s); } } +HMENU +TranslateOneMenu(int i, HMENU subMenu) +{ + int j; + static MENUITEMINFO info; + + info.cbSize = sizeof(MENUITEMINFO); + info.fMask = MIIM_STATE | MIIM_TYPE; + for(j=GetMenuItemCount(subMenu)-1; j>=0; j--){ + char buf[MSG_SIZ]; + info.dwTypeData = buf; + info.cch = sizeof(buf); + GetMenuItemInfo(subMenu, j, TRUE, &info); + if(i < 10) { + if(menuText[i][j]) safeStrCpy(buf, menuText[i][j], sizeof(buf)/sizeof(buf[0]) ); + else menuText[i][j] = strdup(buf); // remember original on first change + } + if(buf[0] == NULLCHAR) continue; + info.dwTypeData = T_(buf); + info.cch = strlen(buf)+1; + SetMenuItemInfo(subMenu, j, TRUE, &info); + } + return subMenu; +} + void TranslateMenus(int addLanguage) { - int i, j; + int i; WIN32_FIND_DATA fileData; HANDLE hFind; #define IDM_English 1895 @@ -427,20 +450,7 @@ TranslateMenus(int addLanguage) HMENU subMenu = GetSubMenu(mainMenu, i); ModifyMenu(mainMenu, i, MF_STRING|MF_BYPOSITION|MF_POPUP|EnableMenuItem(mainMenu, i, MF_BYPOSITION), (UINT) subMenu, T_(menuBarText[tinyLayout][i])); - for(j=GetMenuItemCount(subMenu)-1; j>=0; j--){ - char buf[MSG_SIZ]; - UINT k = GetMenuItemID(subMenu, j); - if(menuText[i][j]) - safeStrCpy(buf, menuText[i][j], sizeof(buf)/sizeof(buf[0]) ); else { - GetMenuString(subMenu, j, buf, MSG_SIZ, MF_BYPOSITION); - menuText[i][j] = strdup(buf); // remember original on first change - } - if(buf[0] == NULLCHAR) continue; -//fprintf(debugFP, "menu(%d,%d) = %s (%08x, %08x) %d\n", i, j, buf, mainMenu, subMenu, k); - ModifyMenu(subMenu, j, MF_STRING|MF_BYPOSITION - |CheckMenuItem(subMenu, j, MF_BYPOSITION) - |EnableMenuItem(subMenu, j, MF_BYPOSITION), k, T_(buf)); - } + TranslateOneMenu(i, subMenu); } DrawMenuBar(hwndMain); } @@ -549,10 +559,10 @@ MyButtonDesc buttonDesc[N_BUTTONS] = }; int tinyLayout = 0, smallLayout = 0; -#define MENU_BAR_ITEMS 7 +#define MENU_BAR_ITEMS 9 char *menuBarText[2][MENU_BAR_ITEMS+1] = { - { N_("&File"), N_("&Mode"), N_("&Action"), N_("&Step"), N_("&Options"), N_("&Help"), NULL }, - { N_("&F"), N_("&M"), N_("&A"), N_("&S"), N_("&O"), N_("&H"), NULL }, + { N_("&File"), N_("&Edit"), N_("&View"), N_("&Mode"), N_("&Action"), N_("E&ngine"), N_("&Options"), N_("&Help"), NULL }, + { N_("&F"), N_("&E"), N_("&V"), N_("&M"), N_("&A"), N_("&N"), N_("&O"), N_("&H"), NULL }, }; @@ -756,6 +766,7 @@ WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, } JAWS_INIT + TranslateMenus(1); // InitCommonControlsEx(&ex); InitCommonControls(); @@ -884,6 +895,8 @@ SetUserLogo() snprintf(oldUserName, MSG_SIZ, "logos\\%s.bmp", curName); userLogo = LoadImage( 0, oldUserName, IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE ); safeStrCpy(oldUserName, curName, sizeof(oldUserName)/sizeof(oldUserName[0]) ); + if(userLogo == NULL) + userLogo = LoadImage( 0, "logos\\dummy.bmp", IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE ); } } } @@ -1048,7 +1061,6 @@ InitInstance(HINSTANCE hInstance, int nCmdShow, LPSTR lpCmdLine) } InitDrawingSizes(boardSize, 0); - TranslateMenus(1); InitMenuChecks(); buttonCount = GetSystemMetrics(SM_CMOUSEBUTTONS); @@ -2459,7 +2471,7 @@ InitDrawingSizes(BoardSize boardSize, int flags) pieceBitmap[2][WhiteBishop] = DoLoadBitmap(hInst, "b", squareSize, "w"); pieceBitmap[2][WhiteRook] = DoLoadBitmap(hInst, "r", squareSize, "w"); pieceBitmap[2][WhiteKing] = DoLoadBitmap(hInst, "k", squareSize, "w"); - if( gameInfo.variant == VariantShogi && (squareSize==72 || squareSize==49)) { + if( gameInfo.variant == VariantShogi && squareSize <= 72 && squareSize >= 33) { // in Shogi, Hijack the unused Queen for Lance pieceBitmap[0][WhiteQueen] = DoLoadBitmap(hInst, "l", squareSize, "s"); pieceBitmap[1][WhiteQueen] = DoLoadBitmap(hInst, "l", squareSize, "o"); @@ -2486,14 +2498,24 @@ InitDrawingSizes(BoardSize boardSize, int flags) pieceBitmap[1][WhiteLance] = DoLoadBitmap(hInst, "l", squareSize, "o"); pieceBitmap[2][WhiteLance] = DoLoadBitmap(hInst, "l", squareSize, "w"); } else { // Smirf-like - pieceBitmap[0][WhiteAngel] = DoLoadBitmap(hInst, "aa", squareSize, "s"); - pieceBitmap[1][WhiteAngel] = DoLoadBitmap(hInst, "aa", squareSize, "o"); - pieceBitmap[2][WhiteAngel] = DoLoadBitmap(hInst, "aa", squareSize, "w"); + if(gameInfo.variant == VariantSChess) { + pieceBitmap[0][WhiteAngel] = DoLoadBitmap(hInst, "v", squareSize, "s"); + pieceBitmap[1][WhiteAngel] = DoLoadBitmap(hInst, "v", squareSize, "o"); + pieceBitmap[2][WhiteAngel] = DoLoadBitmap(hInst, "v", squareSize, "w"); + } else { + pieceBitmap[0][WhiteAngel] = DoLoadBitmap(hInst, "aa", squareSize, "s"); + pieceBitmap[1][WhiteAngel] = DoLoadBitmap(hInst, "aa", squareSize, "o"); + pieceBitmap[2][WhiteAngel] = DoLoadBitmap(hInst, "aa", squareSize, "w"); + } } if(gameInfo.variant == VariantGothic) { // Vortex-like pieceBitmap[0][WhiteMarshall] = DoLoadBitmap(hInst, "cv", squareSize, "s"); pieceBitmap[1][WhiteMarshall] = DoLoadBitmap(hInst, "cv", squareSize, "o"); pieceBitmap[2][WhiteMarshall] = DoLoadBitmap(hInst, "cv", squareSize, "w"); + } else if(gameInfo.variant == VariantSChess && (squareSize == 49 || squareSize == 72)) { + pieceBitmap[0][WhiteMarshall] = DoLoadBitmap(hInst, "e", squareSize, "s"); + pieceBitmap[1][WhiteMarshall] = DoLoadBitmap(hInst, "e", squareSize, "o"); + pieceBitmap[2][WhiteMarshall] = DoLoadBitmap(hInst, "e", squareSize, "w"); } else { // WinBoard standard pieceBitmap[0][WhiteMarshall] = DoLoadBitmap(hInst, "c", squareSize, "s"); pieceBitmap[1][WhiteMarshall] = DoLoadBitmap(hInst, "c", squareSize, "o"); @@ -2942,7 +2964,7 @@ VOID RebuildTextureSquareInfo() /* [AS] Arrow highlighting support */ -static int A_WIDTH = 5; /* Width of arrow body */ +static double A_WIDTH = 5; /* Width of arrow body */ #define A_HEIGHT_FACTOR 6 /* Length of arrow "point", relative to body width */ #define A_WIDTH_FACTOR 3 /* Width of arrow "point", relative to body width */ @@ -2966,50 +2988,50 @@ VOID DrawArrowBetweenPoints( HDC hdc, int s_x, int s_y, int d_x, int d_y ) if( d_x == s_x ) { int h = (d_y > s_y) ? +A_WIDTH*A_HEIGHT_FACTOR : -A_WIDTH*A_HEIGHT_FACTOR; - arrow[0].x = s_x + A_WIDTH; + arrow[0].x = s_x + A_WIDTH + 0.5; arrow[0].y = s_y; - arrow[1].x = s_x + A_WIDTH; + arrow[1].x = s_x + A_WIDTH + 0.5; arrow[1].y = d_y - h; - arrow[2].x = s_x + A_WIDTH*A_WIDTH_FACTOR; + arrow[2].x = arrow[1].x + A_WIDTH*(A_WIDTH_FACTOR-1) + 0.5; arrow[2].y = d_y - h; arrow[3].x = d_x; arrow[3].y = d_y; - arrow[4].x = s_x - A_WIDTH*A_WIDTH_FACTOR; - arrow[4].y = d_y - h; - - arrow[5].x = s_x - A_WIDTH; + arrow[5].x = arrow[1].x - 2*A_WIDTH + 0.5; arrow[5].y = d_y - h; - arrow[6].x = s_x - A_WIDTH; + arrow[4].x = arrow[5].x - A_WIDTH*(A_WIDTH_FACTOR-1) + 0.5; + arrow[4].y = d_y - h; + + arrow[6].x = arrow[1].x - 2*A_WIDTH + 0.5; arrow[6].y = s_y; } else if( d_y == s_y ) { int w = (d_x > s_x) ? +A_WIDTH*A_HEIGHT_FACTOR : -A_WIDTH*A_HEIGHT_FACTOR; arrow[0].x = s_x; - arrow[0].y = s_y + A_WIDTH; + arrow[0].y = s_y + A_WIDTH + 0.5; arrow[1].x = d_x - w; - arrow[1].y = s_y + A_WIDTH; + arrow[1].y = s_y + A_WIDTH + 0.5; arrow[2].x = d_x - w; - arrow[2].y = s_y + A_WIDTH*A_WIDTH_FACTOR; + arrow[2].y = arrow[1].y + A_WIDTH*(A_WIDTH_FACTOR-1) + 0.5; arrow[3].x = d_x; arrow[3].y = d_y; - arrow[4].x = d_x - w; - arrow[4].y = s_y - A_WIDTH*A_WIDTH_FACTOR; - arrow[5].x = d_x - w; - arrow[5].y = s_y - A_WIDTH; + arrow[5].y = arrow[1].y - 2*A_WIDTH + 0.5; + + arrow[4].x = d_x - w; + arrow[4].y = arrow[5].y - A_WIDTH*(A_WIDTH_FACTOR-1) + 0.5; arrow[6].x = s_x; - arrow[6].y = s_y - A_WIDTH; + arrow[6].y = arrow[1].y - 2*A_WIDTH + 0.5; } else { /* [AS] Needed a lot of paper for this! :-) */ @@ -3026,8 +3048,8 @@ VOID DrawArrowBetweenPoints( HDC hdc, int s_x, int s_y, int d_x, int d_y ) arrow[0].x = Round(x - j); arrow[0].y = Round(y + j*dx); - arrow[1].x = Round(x + j); - arrow[1].y = Round(y - j*dx); + arrow[1].x = Round(arrow[0].x + 2*j); // [HGM] prevent width to be affected by rounding twice + arrow[1].y = Round(arrow[0].y - 2*j*dx); if( d_x > s_x ) { x = (double) d_x - k; @@ -3038,20 +3060,22 @@ VOID DrawArrowBetweenPoints( HDC hdc, int s_x, int s_y, int d_x, int d_y ) y = (double) d_y + k*dy; } - arrow[2].x = Round(x + j); - arrow[2].y = Round(y - j*dx); + x = Round(x); y = Round(y); // [HGM] make sure width of shaft is rounded the same way on both ends + + arrow[6].x = Round(x - j); + arrow[6].y = Round(y + j*dx); + + arrow[2].x = Round(arrow[6].x + 2*j); + arrow[2].y = Round(arrow[6].y - 2*j*dx); - arrow[3].x = Round(x + j*A_WIDTH_FACTOR); - arrow[3].y = Round(y - j*A_WIDTH_FACTOR*dx); + arrow[3].x = Round(arrow[2].x + j*(A_WIDTH_FACTOR-1)); + arrow[3].y = Round(arrow[2].y - j*(A_WIDTH_FACTOR-1)*dx); arrow[4].x = d_x; arrow[4].y = d_y; - arrow[5].x = Round(x - j*A_WIDTH_FACTOR); - arrow[5].y = Round(y + j*A_WIDTH_FACTOR*dx); - - arrow[6].x = Round(x - j); - arrow[6].y = Round(y + j*dx); + arrow[5].x = Round(arrow[6].x - j*(A_WIDTH_FACTOR-1)); + arrow[5].y = Round(arrow[6].y + j*(A_WIDTH_FACTOR-1)*dx); } Polygon( hdc, arrow, 7 ); @@ -3076,20 +3100,20 @@ VOID DrawArrowBetweenSquares( HDC hdc, int s_col, int s_row, int d_col, int d_ro SquareToPos( d_row, d_col, &d_x, &d_y); if( d_y > s_y ) { - d_y += squareSize / 4; + d_y += squareSize / 2 - squareSize / 4; // [HGM] round towards same centers on all sides! } else if( d_y < s_y ) { - d_y += 3 * squareSize / 4; + d_y += squareSize / 2 + squareSize / 4; } else { d_y += squareSize / 2; } if( d_x > s_x ) { - d_x += squareSize / 4; + d_x += squareSize / 2 - squareSize / 4; } else if( d_x < s_x ) { - d_x += 3 * squareSize / 4; + d_x += squareSize / 2 + squareSize / 4; } else { d_x += squareSize / 2; @@ -3099,7 +3123,7 @@ VOID DrawArrowBetweenSquares( HDC hdc, int s_col, int s_row, int d_col, int d_ro s_y += squareSize / 2; /* Adjust width */ - A_WIDTH = squareSize / 14; + A_WIDTH = squareSize / 14.; //[HGM] make float /* Draw */ stLB.lbStyle = BS_SOLID; @@ -3370,6 +3394,48 @@ DrawLogoOnDC(HDC hdc, RECT logoRect, HBITMAP logo) DeleteDC(tmphdc); } +VOID +DisplayLogos() +{ + if(logoHeight) { + HDC hdc = GetDC(hwndMain); + HBITMAP whiteLogo = (HBITMAP) first.programLogo, blackLogo = (HBITMAP) second.programLogo; + if(appData.autoLogo) { + + switch(gameMode) { // pick logos based on game mode + case IcsObserving: + whiteLogo = second.programLogo; // ICS logo + blackLogo = second.programLogo; + default: + break; + case IcsPlayingWhite: + if(!appData.zippyPlay) whiteLogo = userLogo; + blackLogo = second.programLogo; // ICS logo + break; + case IcsPlayingBlack: + whiteLogo = second.programLogo; // ICS logo + blackLogo = appData.zippyPlay ? first.programLogo : userLogo; + break; + case TwoMachinesPlay: + if(first.twoMachinesColor[0] == 'b') { + whiteLogo = second.programLogo; + blackLogo = first.programLogo; + } + break; + case MachinePlaysWhite: + blackLogo = userLogo; + break; + case MachinePlaysBlack: + whiteLogo = userLogo; + blackLogo = first.programLogo; + } + } + DrawLogoOnDC(hdc, leftLogoRect, flipClock ? blackLogo : whiteLogo); + DrawLogoOnDC(hdc, rightLogoRect, flipClock ? whiteLogo : blackLogo); + ReleaseDC(hwndMain, hdc); + } +} + static HDC hdcSeek; // [HGM] seekgraph @@ -3505,7 +3571,7 @@ HDCDrawPosition(HDC hdc, BOOLEAN repaint, Board board) if(--board[dragInfo.from.y][dragInfo.from.x-1] == 0 ) board[dragInfo.from.y][dragInfo.from.x] = EmptySquare; } else - board[dragInfo.from.y][dragInfo.from.x] = EmptySquare; + board[dragInfo.from.y][dragInfo.from.x] = gatingPiece; } /* Figure out which squares need updating by comparing the @@ -3667,6 +3733,7 @@ HDCDrawPosition(HDC hdc, BOOLEAN repaint, Board board) if(explodeInfo.radius) { // [HGM] atomic HBRUSH oldBrush; int x, y, r=(explodeInfo.radius * squareSize)/100; + ChessSquare piece = board[explodeInfo.fromY][explodeInfo.fromX]; board[explodeInfo.fromY][explodeInfo.fromX] = EmptySquare; // suppress display of capturer SquareToPos(explodeInfo.toY, explodeInfo.toX, &x, &y); x += squareSize/2; @@ -3679,6 +3746,7 @@ HDCDrawPosition(HDC hdc, BOOLEAN repaint, Board board) DrawHighlightsOnDC(hdcmem, &highlightInfo, HIGHLIGHT_PEN); DrawHighlightsOnDC(hdcmem, &premoveHighlightInfo, PREMOVE_PEN); DrawBoardOnDC(hdcmem, board, tmphdc); + board[explodeInfo.fromY][explodeInfo.fromX] = piece; oldBrush = SelectObject(hdcmem, explodeBrush); Ellipse(hdcmem, x-r, y-r, x+r, y+r); SelectObject(hdcmem, oldBrush); @@ -3706,41 +3774,6 @@ HDCDrawPosition(HDC hdc, BOOLEAN repaint, Board board) } } } - if(logoHeight) { - HBITMAP whiteLogo = (HBITMAP) first.programLogo, blackLogo = (HBITMAP) second.programLogo; - if(appData.autoLogo) { - - switch(gameMode) { // pick logos based on game mode - case IcsObserving: - whiteLogo = second.programLogo; // ICS logo - blackLogo = second.programLogo; - default: - break; - case IcsPlayingWhite: - if(!appData.zippyPlay) whiteLogo = userLogo; - blackLogo = second.programLogo; // ICS logo - break; - case IcsPlayingBlack: - whiteLogo = second.programLogo; // ICS logo - blackLogo = appData.zippyPlay ? first.programLogo : userLogo; - break; - case TwoMachinesPlay: - if(first.twoMachinesColor[0] == 'b') { - whiteLogo = second.programLogo; - blackLogo = first.programLogo; - } - break; - case MachinePlaysWhite: - blackLogo = userLogo; - break; - case MachinePlaysBlack: - whiteLogo = userLogo; - blackLogo = first.programLogo; - } - } - DrawLogoOnDC(hdc, leftLogoRect, flipClock ? blackLogo : whiteLogo); - DrawLogoOnDC(hdc, rightLogoRect, flipClock ? whiteLogo : blackLogo); - } if( appData.highlightMoveWithArrow ) { DrawArrowHighlight(hdcmem); @@ -3955,6 +3988,7 @@ PaintProc(HWND hwnd) &messageRect, messageText, strlen(messageText), NULL); SelectObject(hdc, oldFont); DisplayBothClocks(); + DisplayLogos(); } EndPaint(hwnd,&ps); } @@ -4073,26 +4107,14 @@ MouseEvent(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) x = BOARD_WIDTH - 1 - x; } + shiftKey = GetKeyState(VK_SHIFT) < 0; // [HGM] remember last shift status + switch (message) { case WM_LBUTTONDOWN: if (PtInRect((LPRECT) &whiteRect, pt)) { - if (gameMode == EditPosition) { - SetWhiteToPlayEvent(); - } else if (gameMode == EditGame || GetKeyState(VK_SHIFT) < 0) { - AdjustClock(flipClock, -1); - } else if (gameMode == IcsPlayingBlack || - gameMode == MachinePlaysWhite) { - CallFlagEvent(); - } + ClockClick(flipClock); } else if (PtInRect((LPRECT) &blackRect, pt)) { - if (gameMode == EditPosition) { - SetBlackToPlayEvent(); - } else if (gameMode == EditGame || GetKeyState(VK_SHIFT) < 0) { - AdjustClock(!flipClock, -1); - } else if (gameMode == IcsPlayingWhite || - gameMode == MachinePlaysBlack) { - CallFlagEvent(); - } + ClockClick(!flipClock); } dragInfo.start.x = dragInfo.start.y = -1; dragInfo.from = dragInfo.start; @@ -4271,19 +4293,20 @@ Promotion(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) Translate(hDlg, DLG_PromotionKing); ShowWindow(GetDlgItem(hDlg, PB_King), (!appData.testLegality || gameInfo.variant == VariantSuicide || + gameInfo.variant == VariantSpartan && !WhiteOnMove(currentMove) || gameInfo.variant == VariantGiveaway || gameInfo.variant == VariantSuper ) ? SW_SHOW : SW_HIDE); /* [HGM] Only allow C & A promotions if these pieces are defined */ ShowWindow(GetDlgItem(hDlg, PB_Archbishop), - ((PieceToChar(WhiteAngel) >= 'A' && + ((PieceToChar(WhiteAngel) >= 'A' && WhiteOnMove(currentMove) && PieceToChar(WhiteAngel) != '~') || - (PieceToChar(BlackAngel) >= 'A' && + (PieceToChar(BlackAngel) >= 'A' && !WhiteOnMove(currentMove) && PieceToChar(BlackAngel) != '~') ) ? SW_SHOW : SW_HIDE); ShowWindow(GetDlgItem(hDlg, PB_Chancellor), - ((PieceToChar(WhiteMarshall) >= 'A' && + ((PieceToChar(WhiteMarshall) >= 'A' && WhiteOnMove(currentMove) && PieceToChar(WhiteMarshall) != '~') || - (PieceToChar(BlackMarshall) >= 'A' && + (PieceToChar(BlackMarshall) >= 'A' && !WhiteOnMove(currentMove) && PieceToChar(BlackMarshall) != '~') ) ? SW_SHOW : SW_HIDE); /* [HGM] Hide B & R button in Shogi, use Q as promote, N as defer */ @@ -4293,12 +4316,11 @@ Promotion(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) ShowWindow(GetDlgItem(hDlg, PB_Bishop), gameInfo.variant != VariantShogi ? SW_SHOW : SW_HIDE); - ShowWindow(GetDlgItem(hDlg, IDC_Yes), - gameInfo.variant == VariantShogi ? - SW_SHOW : SW_HIDE); - ShowWindow(GetDlgItem(hDlg, IDC_No), - gameInfo.variant == VariantShogi ? - SW_SHOW : SW_HIDE); + if(gameInfo.variant == VariantShogi) { + SetDlgItemText(hDlg, PB_Queen, "YES"); + SetDlgItemText(hDlg, PB_Knight, "NO"); + SetWindowText(hDlg, "Promote?"); + } ShowWindow(GetDlgItem(hDlg, IDC_Centaur), gameInfo.variant == VariantSuper ? SW_SHOW : SW_HIDE); @@ -4315,31 +4337,30 @@ 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 ? '+' : PieceToChar(BlackQueen); + promoChar = gameInfo.variant == VariantShogi ? '+' : ToLower(PieceToChar(WhiteOnMove(currentMove) ? WhiteQueen : BlackQueen)); break; case PB_Rook: - promoChar = PieceToChar(BlackRook); + promoChar = ToLower(PieceToChar(WhiteOnMove(currentMove) ? WhiteRook : BlackRook)); + if(gameInfo.variant == VariantSpartan && !WhiteOnMove(currentMove)) promoChar = PieceToChar(BlackDragon); break; case PB_Bishop: - promoChar = PieceToChar(BlackBishop); + promoChar = ToLower(PieceToChar(WhiteOnMove(currentMove) ? WhiteBishop : BlackBishop)); + if(gameInfo.variant == VariantSpartan && !WhiteOnMove(currentMove)) promoChar = PieceToChar(BlackAlfil); break; case PB_Chancellor: - promoChar = PieceToChar(BlackMarshall); + promoChar = ToLower(PieceToChar(WhiteOnMove(currentMove) ? WhiteMarshall : BlackMarshall)); break; case PB_Archbishop: - promoChar = PieceToChar(BlackAngel); + promoChar = ToLower(PieceToChar(WhiteOnMove(currentMove) ? WhiteAngel : BlackAngel)); break; case PB_Knight: - promoChar = gameInfo.variant == VariantShogi ? '=' : PieceToChar(BlackKnight); + promoChar = gameInfo.variant == VariantShogi ? '=' : PieceToChar(WhiteOnMove(currentMove) ? WhiteKnight : BlackKnight); break; default: return FALSE; } + if(promoChar == '.') return FALSE; // invalid piece chosen EndDialog(hDlg, TRUE); /* Exit the dialog */ - /* [HGM] Call FinishMove rather than UserMoveEvent, as we - only show the popup when we are already sure the move is valid or - legal. We pass a faulty move type, but the kludge is that FinishMove - will figure out it is a promotion from the promoChar. */ UserMoveEvent(fromX, fromY, toX, toY, promoChar); fromX = fromY = -1; if (!appData.highlightLastMove) { @@ -4814,10 +4835,13 @@ WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) break; case IDM_Match: // [HGM] match: flows into next case, after setting Match Mode and nr of Games - if(gameMode != BeginningOfGame) break; // allow menu item to remain enabled for better mode highligting + if(gameMode != BeginningOfGame) { // allow menu item to remain enabled for better mode highligting + DisplayError(_("You can only start a match from the initial position."), 0); break; + } matchMode = 2;// distinguish from command-line-triggered case (matchMode=1) appData.matchGames = appData.defaultMatchGames; matchGame = 1; + first.matchWins = second.matchWins = 0; case IDM_TwoMachines: TwoMachinesEvent(); @@ -4887,11 +4911,13 @@ WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) break; case IDM_EditGame: + case IDM_EditGame2: EditGameEvent(); SAY("edit game"); break; case IDM_EditPosition: + case IDM_EditPosition2: EditPositionEvent(); SAY("enter a FEN string or setup a position on the board using the control R pop up menu"); break; @@ -4904,11 +4930,25 @@ WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) ShowGameListProc(); break; + case IDM_EditProgs1: + EditTagsPopUp(firstChessProgramNames, &firstChessProgramNames); + break; + + case IDM_EditProgs2: + EditTagsPopUp(secondChessProgramNames, &secondChessProgramNames); + break; + + case IDM_EditServers: + EditTagsPopUp(icsNames, &icsNames); + break; + case IDM_EditTags: + case IDM_Tags: EditTagsProc(); break; case IDM_EditComment: + case IDM_Comment: if (commentUp && editComment) { CommentPopDown(); } else { @@ -5022,7 +5062,7 @@ WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) case IDM_FlipClock: flipClock = !flipClock; DisplayBothClocks(); - DrawPosition(FALSE, NULL); + DisplayLogos(); break; case IDM_MuteSounds: @@ -5049,6 +5089,8 @@ WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) break; case IDM_Engine2Options: + savedHwnd = hwnd; + if(WaitForSecond(SettingsMenuIfReady)) break; EngineOptionsPopup(hwnd, &second); break; @@ -5707,12 +5749,12 @@ OpenFileDialog(HWND hwnd, char *write, char *defName, char *defExt, // [HGM] dia if (fileName == NULL) fileName = buf1; if (defName == NULL) { - safeStrCpy(fileName, "*.", sizeof(fileName)/sizeof(fileName[0]) ); + safeStrCpy(fileName, "*.", 3 ); strcat(fileName, defExt); } else { - safeStrCpy(fileName, defName, sizeof(fileName)/sizeof(fileName[0]) ); + safeStrCpy(fileName, defName, MSG_SIZ ); } - if (fileTitle) safeStrCpy(fileTitle, "", sizeof(fileTitle)/sizeof(fileTitle[0]) ); + if (fileTitle) safeStrCpy(fileTitle, "", MSG_SIZ ); if (number) *number = 0; openFileName.lStructSize = sizeof(OPENFILENAME); @@ -5769,6 +5811,7 @@ MenuPopup(HWND hwnd, POINT pt, HMENU hmenu, UINT def) * menu that TrackPopupMenu displays. */ hmenuTrackPopup = GetSubMenu(hmenu, 0); + TranslateOneMenu(10, hmenuTrackPopup); SetMenuDefaultItem(hmenuTrackPopup, def, FALSE); @@ -6207,7 +6250,7 @@ CommentDialog(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) sizeY = newSizeY; } } - SendDlgItemMessage( hDlg, OPT_CommentText, EM_SETEVENTMASK, 0, ENM_MOUSEEVENTS ); + SendDlgItemMessage( hDlg, OPT_CommentText, EM_SETEVENTMASK, 0, ENM_MOUSEEVENTS | ENM_KEYEVENTS ); return FALSE; case WM_COMMAND: /* message: received a command */ @@ -6256,13 +6299,19 @@ CommentDialog(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) if( wParam == OPT_CommentText ) { MSGFILTER * lpMF = (MSGFILTER *) lParam; - if( lpMF->msg == WM_RBUTTONDOWN && (lpMF->wParam & (MK_CONTROL | MK_SHIFT)) == 0 ) { + if( lpMF->msg == WM_RBUTTONDOWN && (lpMF->wParam & (MK_CONTROL | MK_SHIFT)) == 0 || + lpMF->msg == WM_CHAR && lpMF->wParam == '\022' ) { POINTL pt; LRESULT index; pt.x = LOWORD( lpMF->lParam ); pt.y = HIWORD( lpMF->lParam ); + if(lpMF->msg == WM_CHAR) { + CHARRANGE sel; + SendDlgItemMessage( hDlg, OPT_CommentText, EM_EXGETSEL, 0, (LPARAM) &sel ); + index = sel.cpMin; + } else index = SendDlgItemMessage( hDlg, OPT_CommentText, EM_CHARFROMPOS, 0, (LPARAM) &pt ); hwndText = GetDlgItem(hDlg, OPT_CommentText); // cloned from above @@ -6306,7 +6355,7 @@ EitherCommentPopUp(int index, char *title, char *str, BOOLEAN edit) FARPROC lpProc; char *p, *q; - CheckMenuItem(GetMenu(hwndMain), IDM_EditComment, edit ? MF_CHECKED : MF_UNCHECKED); + CheckMenuItem(GetMenu(hwndMain), IDM_Comment, edit ? MF_CHECKED : MF_UNCHECKED); if (str == NULL) str = ""; p = (char *) malloc(2 * strlen(str) + 2); @@ -6365,7 +6414,9 @@ TypeInMoveDialog(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) case WM_COMMAND: switch (LOWORD(wParam)) { - case IDOK: + case IDOK: + + shiftKey = GetKeyState(VK_SHIFT) < 0; // [HGM] remember last shift status GetDlgItemText(hDlg, OPT_Move, move, sizeof(move)); { int n; Board board; // [HGM] FENedit @@ -6391,8 +6442,6 @@ TypeInMoveDialog(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) if(!ok && move[0] >= 'a') { move[0] += 'A' - 'a'; ok = 2; } // [HGM] try also capitalized if (ok==1 || ok && ParseOneMove(move, gameMode == EditPosition ? blackPlaysFirst : currentMove, &moveType, &fromX, &fromY, &toX, &toY, &promoChar)) { - if (gameMode != Training) - forwardMostMove = currentMove; UserMoveEvent(fromX, fromY, toX, toY, promoChar); } else { DisplayMoveError(_("Could not parse move")); @@ -6795,6 +6844,7 @@ CommandX(HWND hwnd, char *command, BOOLEAN getname, BOOLEAN immediate) SendMessage(hwnd, EM_GETSELTEXT, 0, (LPARAM) name); } if (immediate) { + if(strstr(command, "%s")) snprintf(buf, MSG_SIZ, command, name); else snprintf(buf, MSG_SIZ, "%s %s", command, name); SetWindowText(hInput, buf); SendMessage(hInput, WM_CHAR, '\r', 0); @@ -6818,6 +6868,7 @@ ConsoleTextSubclass(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) switch (message) { case WM_KEYDOWN: if (!(GetKeyState(VK_CONTROL) & ~1)) break; + if(wParam=='R') return 0; switch (wParam) { case VK_PRIOR: SendMessage(hwnd, EM_LINESCROLL, 0, -999999); @@ -6851,7 +6902,8 @@ ConsoleTextSubclass(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) SendMessage(hInput, message, wParam, lParam); } return 0; - } // [HGM] navigate: for Ctrl+R, flow into nex case (moved up here) to summon up menu + } // [HGM] navigate: for Ctrl+R, flow into next case (moved up here) to summon up menu + lParam = -1; case WM_RBUTTONDOWN: if (!(GetKeyState(VK_SHIFT) & ~1)) { /* Move selection here if it was empty */ @@ -6860,7 +6912,7 @@ ConsoleTextSubclass(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) pt.y = HIWORD(lParam); SendMessage(hwnd, EM_EXGETSEL, 0, (LPARAM)&sel); if (sel.cpMin == sel.cpMax) { - sel.cpMin = SendMessage(hwnd, EM_CHARFROMPOS, 0, (LPARAM)&pt); /*doc is wrong*/ + if(lParam != -1) sel.cpMin = SendMessage(hwnd, EM_CHARFROMPOS, 0, (LPARAM)&pt); /*doc is wrong*/ sel.cpMax = sel.cpMin; SendMessage(hwnd, EM_EXSETSEL, 0, (LPARAM)&sel); } @@ -7424,7 +7476,7 @@ DisplayAClock(HDC hdc, int timeRemaining, int highlight, rect, str, strlen(str), NULL); if(logoHeight > 0 && appData.clockMode) { RECT r; - snprintf(buf, sizeof(buf)/sizeof(buf[0]), "%s %s", buf+7, flagFell); + str += strlen(color)+2; r.top = rect->top + logoHeight/2; r.left = rect->left; r.right = rect->right; @@ -7785,11 +7837,13 @@ Enables ncpEnables[] = { { IDM_NewChat, MF_BYCOMMAND|MF_GRAYED }, { IDM_Engine1Options, MF_BYCOMMAND|MF_GRAYED }, { IDM_Engine2Options, MF_BYCOMMAND|MF_GRAYED }, + { IDM_Sounds, MF_BYCOMMAND|MF_GRAYED }, { -1, -1 } }; Enables trainingOnEnables[] = { { IDM_EditComment, MF_BYCOMMAND|MF_GRAYED }, + { IDM_Comment, MF_BYCOMMAND|MF_GRAYED }, { IDM_Pause, MF_BYCOMMAND|MF_GRAYED }, { IDM_Forward, MF_BYCOMMAND|MF_GRAYED }, { IDM_Backward, MF_BYCOMMAND|MF_GRAYED }, @@ -7802,6 +7856,7 @@ Enables trainingOnEnables[] = { Enables trainingOffEnables[] = { { IDM_EditComment, MF_BYCOMMAND|MF_ENABLED }, + { IDM_Comment, MF_BYCOMMAND|MF_ENABLED }, { IDM_Pause, MF_BYCOMMAND|MF_ENABLED }, { IDM_Forward, MF_BYCOMMAND|MF_ENABLED }, { IDM_Backward, MF_BYCOMMAND|MF_ENABLED }, @@ -7958,6 +8013,7 @@ ModeHighlight() MF_BYCOMMAND|MF_UNCHECKED); } } + DisplayLogos(); // [HGM] logos: mode change could have altered logos } VOID @@ -7965,8 +8021,8 @@ SetICSMode() { HMENU hmenu = GetMenu(hwndMain); SetMenuEnables(hmenu, icsEnables); - EnableMenuItem(GetSubMenu(hmenu, OPTIONS_POS), ICS_POS, - MF_BYPOSITION|MF_ENABLED); + EnableMenuItem(GetSubMenu(hmenu, OPTIONS_POS), IDM_IcsOptions, + MF_BYCOMMAND|MF_ENABLED); #if ZIPPY if (appData.zippyPlay) { SetMenuEnables(hmenu, zippyEnables); @@ -7988,8 +8044,6 @@ SetNCPMode() { HMENU hmenu = GetMenu(hwndMain); SetMenuEnables(hmenu, ncpEnables); - EnableMenuItem(GetSubMenu(hmenu, OPTIONS_POS), SOUNDS_POS, - MF_BYPOSITION|MF_GRAYED); DrawMenuBar(hwndMain); } @@ -8499,7 +8553,7 @@ CommentPopUp(char *title, char *str) VOID CommentPopDown(void) { - CheckMenuItem(GetMenu(hwndMain), IDM_EditComment, MF_UNCHECKED); + CheckMenuItem(GetMenu(hwndMain), IDM_Comment, MF_UNCHECKED); if (commentDialog) { ShowWindow(commentDialog, SW_HIDE); } @@ -9613,26 +9667,26 @@ static void Tween( POINT * start, POINT * mid, POINT * finish, int factor, POINT frames[], int * nFrames); +#define kFactor 4 + void -AnimateAtomicCapture(int fromX, int fromY, int toX, int toY, int nFrames) +AnimateAtomicCapture(Board board, int fromX, int fromY, int toX, int toY) { // [HGM] atomic: animate blast wave int i; -if(appData.debugMode) fprintf(debugFP, "exploding (%d,%d)\n", toX, toY); + explodeInfo.fromX = fromX; explodeInfo.fromY = fromY; explodeInfo.toX = toX; explodeInfo.toY = toY; - for(i=1; i