X-Git-Url: http://winboard.nl/cgi-bin?a=blobdiff_plain;f=winboard%2Fwinboard.c;h=bd829b4859efb9638ff6192e46eddd0bbbc18731;hb=1d2eec53fb91655d002d67fe54b5256f0a49719b;hp=971309b91ccc02b42dcdf0112365b706dc3a88db;hpb=a24992eef4621e0f45993a38cc6770cdb631d2cc;p=xboard.git diff --git a/winboard/winboard.c b/winboard/winboard.c index 971309b..bd829b4 100644 --- a/winboard/winboard.c +++ b/winboard/winboard.c @@ -5,7 +5,8 @@ * Massachusetts. * * Enhancements Copyright 1992-2001, 2002, 2003, 2004, 2005, 2006, - * 2007, 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015 Free Software Foundation, Inc. + * 2007, 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016 Free + * Software Foundation, Inc. * * Enhancements Copyright 2005 Alessandro Scotti * @@ -54,6 +55,10 @@ *------------------------------------------------------------------------ ** See the file ChangeLog for a revision history. */ +#ifndef WINVER +#define WINVER 0x0500 +#endif + #include "config.h" #include @@ -1106,6 +1111,8 @@ InitGeometry() screenGeometry.bottom = screenGeometry.top + screenHeight; } +ChessProgramState broadcast; + BOOL InitInstance(HINSTANCE hInstance, int nCmdShow, LPSTR lpCmdLine) { @@ -1138,7 +1145,18 @@ InitInstance(HINSTANCE hInstance, int nCmdShow, LPSTR lpCmdLine) appData.ringBellAfterMoves = TRUE; } if (appData.debugMode) { - debugFP = fopen(appData.nameOfDebugFile, "w"); + char *c = appData.nameOfDebugFile; + if(strstr(c, "///") == c) { + broadcast.which = "broadcaster"; + broadcast.pr = NoProc; + broadcast.isr = NULL; + broadcast.program = c + 3; + broadcast.dir = "."; + broadcast.host = "localhost"; + StartChessProgram(&broadcast); + debugFP = (FILE*) _fdopen(_open_osfhandle((long)(((ChildProc*)(broadcast.pr))->hTo), _O_WRONLY), "w"); + } else + debugFP = fopen(c, "w"); setbuf(debugFP, NULL); } @@ -2050,6 +2068,7 @@ static int TranslatePieceToFontPiece( int piece ) case WhiteSilver: return PM_WSG; case WhiteLance: + return PM_WL; case WhiteFalcon: return PM_WV; @@ -2179,7 +2198,7 @@ void CreatePiecesFromFont() HBITMAP DoLoadBitmap(HINSTANCE hinst, char *piece, int squareSize, char *suffix) { - char name[128], buf[MSG_SIZ]; + char name[128], buf[MSG_SIZ], *ids = "pnbrqfeicwmohajgdvlsukaacvdklnwpwnwlwswolfgnuzebracameltowersword", *p; snprintf(name, sizeof(name)/sizeof(name[0]), "%s%d%s", piece, squareSize, suffix); if(appData.pieceDirectory[0]) { @@ -2187,6 +2206,30 @@ DoLoadBitmap(HINSTANCE hinst, char *piece, int squareSize, char *suffix) snprintf(buf, MSG_SIZ, "%s\\%s.bmp", appData.pieceDirectory, name); res = LoadImage( 0, buf, IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE ); if(res) return res; + p = strstr(ids, piece); + if(p) { // if we could reconstruct canonical piece number, try the pieceNNN_ format before falling back on built-ins + int n = p - ids; + switch(n) { + case 21: n = WhiteKing; break; + case 22: n = WhiteAngel; break; + case 24: n = WhiteSilver; break; + case 26: n = WhiteDragon; break; + case 28: n = WhiteLion; break; + case 30: n = WhiteTokin; break; + case 32: n = WhitePKnight; break; + case 34: n = WhitePLance; break; + case 36: n = WhitePSilver; break; + case 38: n = WhiteWolf; break; + case 42: n = WhiteGnu; break; + case 45: n = WhiteZebra; break; + case 50: n = WhiteCamel; break; + case 55: n = WhiteTower; break; + case 60: n = WhiteSword; break; + } + snprintf(buf, MSG_SIZ, "%s\\piece%d_%d%s.bmp", appData.pieceDirectory, n, squareSize, suffix); + res = LoadImage( 0, buf, IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE ); + if(res) return res; + } } if (gameInfo.event && strcmp(gameInfo.event, "Easter Egg Hunt") == 0 && @@ -2589,10 +2632,12 @@ InitDrawingSizes(BoardSize boardSize, int flags) piece = (ChessSquare) ((int) piece + 1)) { if (pieceBitmap[i][piece] != NULL) DeleteObject(pieceBitmap[i][piece]); + pieceBitmap[i][piece] = NULL; } } fontBitmapSquareSize = 0; /* [HGM] render: make sure pieces will be recreated, as we might need others now */ + // Orthodox Chess pieces pieceBitmap[0][WhitePawn] = DoLoadBitmap(hInst, "p", squareSize, "s"); pieceBitmap[0][WhiteKnight] = DoLoadBitmap(hInst, "n", squareSize, "s"); @@ -2690,12 +2735,36 @@ InitDrawingSizes(BoardSize boardSize, int flags) pieceBitmap[0][WhiteLance] = DoLoadBitmap(hInst, "l", squareSize, "s"); pieceBitmap[1][WhiteLance] = DoLoadBitmap(hInst, "l", squareSize, "o"); pieceBitmap[2][WhiteLance] = DoLoadBitmap(hInst, "l", squareSize, "w"); + pieceBitmap[0][WhiteAmazon] = DoLoadBitmap(hInst, "l", squareSize, "s"); + pieceBitmap[1][WhiteAmazon] = DoLoadBitmap(hInst, "l", squareSize, "o"); + pieceBitmap[2][WhiteAmazon] = DoLoadBitmap(hInst, "l", squareSize, "w"); 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"); + pieceBitmap[0][WhiteCub] = DoLoadBitmap(hInst, "ln", squareSize, "s"); + pieceBitmap[1][WhiteCub] = DoLoadBitmap(hInst, "ln", squareSize, "o"); + pieceBitmap[2][WhiteCub] = DoLoadBitmap(hInst, "ln", squareSize, "w"); + pieceBitmap[0][WhiteWolf] = DoLoadBitmap(hInst, "wolf", squareSize, "s"); + pieceBitmap[1][WhiteWolf] = DoLoadBitmap(hInst, "wolf", squareSize, "o"); + pieceBitmap[2][WhiteWolf] = DoLoadBitmap(hInst, "wolf", squareSize, "w"); + pieceBitmap[0][WhiteCamel] = DoLoadBitmap(hInst, "camel", squareSize, "s"); + pieceBitmap[1][WhiteCamel] = DoLoadBitmap(hInst, "camel", squareSize, "o"); + pieceBitmap[2][WhiteCamel] = DoLoadBitmap(hInst, "camel", squareSize, "w"); + pieceBitmap[0][WhiteZebra] = DoLoadBitmap(hInst, "zebra", squareSize, "s"); + pieceBitmap[1][WhiteZebra] = DoLoadBitmap(hInst, "zebra", squareSize, "o"); + pieceBitmap[2][WhiteZebra] = DoLoadBitmap(hInst, "n", squareSize, "w"); + pieceBitmap[0][WhiteTower] = DoLoadBitmap(hInst, "tower", squareSize, "s"); + pieceBitmap[1][WhiteTower] = DoLoadBitmap(hInst, "tower", squareSize, "o"); + pieceBitmap[2][WhiteTower] = DoLoadBitmap(hInst, "tower", squareSize, "w"); + pieceBitmap[0][WhiteSword] = DoLoadBitmap(hInst, "sword", squareSize, "s"); + pieceBitmap[1][WhiteSword] = DoLoadBitmap(hInst, "sword", squareSize, "o"); + pieceBitmap[2][WhiteSword] = DoLoadBitmap(hInst, "sword", squareSize, "w"); + pieceBitmap[0][WhiteGnu] = DoLoadBitmap(hInst, "gnu", squareSize, "s"); + pieceBitmap[1][WhiteGnu] = DoLoadBitmap(hInst, "gnu", squareSize, "o"); + pieceBitmap[2][WhiteGnu] = DoLoadBitmap(hInst, "gnu", squareSize, "w"); if(gameInfo.variant == VariantShogi && BOARD_HEIGHT != 7) { /* promoted Gold representations (but not in Tori!)*/ pieceBitmap[0][WhiteCannon] = DoLoadBitmap(hInst, "wp", squareSize, "s"); @@ -2797,6 +2866,15 @@ InitDrawingSizes(BoardSize boardSize, int flags) pieceBitmap[2][WhiteSilver] = DoLoadBitmap(hInst, "sw", squareSize, "w"); minorSize = 0; } + + if(appData.pieceDirectory[0]) for(i=WhitePawn; i= 0x0500 + HBITMAP pbm = PieceBitmap(piece, color ? OUTLINE_PIECE : SOLID_PIECE); + BITMAP b; + GetObject(pbm, sizeof(BITMAP), &b); + if(b.bmBitsPixel == 32) { // for now this is a kludge to indicate bitmaps with alpha channel + BLENDFUNCTION bf; + bf.BlendOp = AC_SRC_OVER; + bf.BlendFlags = 0; + bf.SourceConstantAlpha = 0xFF; + bf.AlphaFormat = AC_SRC_ALPHA; + oldBitmap = SelectObject(tmphdc, pbm); + AlphaBlend(hdc, x, y, tmpSize, tmpSize, tmphdc, 0, 0, tmpSize, tmpSize, bf); + } else +#endif if (color || appData.allWhite ) { oldBitmap = SelectObject(tmphdc, PieceBitmap(piece, WHITE_PIECE)); if( color ) @@ -3038,7 +3130,7 @@ DrawPieceOnDC(HDC hdc, ChessSquare piece, int color, int sqcolor, int x, int y, else BitBlt(hdc, x, y, tmpSize, tmpSize, tmphdc, 0, 0, 0x00B8074A); } - SelectObject(hdc, oldBrush); + if(oldBrush) SelectObject(hdc, oldBrush); SelectObject(tmphdc, oldBitmap); } } @@ -3713,6 +3805,10 @@ void DrawSeekClose() { } + + + + VOID HDCDrawPosition(HDC hdc, BOOLEAN repaint, Board board) { @@ -3933,6 +4029,7 @@ HDCDrawPosition(HDC hdc, BOOLEAN repaint, Board board) explodes. The old and new positions both had an empty square at the destination, but animation has drawn a piece there and we have to remember to erase it. [HGM] moved until after setting lastDrawn */ + lastDrawn[0][animInfo.to.y][animInfo.to.x] = animInfo.piece; } } @@ -4066,7 +4163,12 @@ HDCDrawPosition(HDC hdc, BOOLEAN repaint, Board board) if(saveDiagFlag) { BITMAP b; int i, j=0, m, w, wb, fac=0; char *pData; BITMAPINFOHEADER bih; int color[16], nrColors=0; + HBITMAP src = bufferBitmap, obmp; HDC tmp = CreateCompatibleDC(hdc); + bufferBitmap = CreateCompatibleBitmap(hdc, boardRect.right-boardRect.left, Rect.bottom-Rect.top-2*OUTER_MARGIN); + obmp = SelectObject(tmp, bufferBitmap); + BitBlt(tmp, 0, 0, boardRect.right - boardRect.left, Rect.bottom - Rect.top - 2*OUTER_MARGIN, + tmphdc, boardRect.left, OUTER_MARGIN, SRCCOPY); GetObject(bufferBitmap, sizeof(b), &b); if(pData = malloc(b.bmWidthBytes*b.bmHeight + 10000)) { bih.biSize = sizeof(BITMAPINFOHEADER); @@ -4130,10 +4232,14 @@ HDCDrawPosition(HDC hdc, BOOLEAN repaint, Board board) if(fac) for(i=0; i<16; i++) fputDW(diagFile, color[i]); // write bitmap data + for(i=0; ix, lpwp->y, hwndConsole, &wpConsole ); wpMain.x = lpwp->x; wpMain.y = lpwp->y; + } } break; @@ -6219,6 +6328,8 @@ InitComboStringsFromOption(HANDLE hwndCombo, char *str) str = buf1; } + + SendMessage(hwndCombo, CB_RESETCONTENT, 0, 0); for (;;) { @@ -6342,11 +6453,12 @@ StartupDialog(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) safeStrCpy(buf, "/fcp=", sizeof(buf)/sizeof(buf[0]) ); GetDlgItemText(hDlg, OPT_ChessEngineName, buf + strlen(buf), sizeof(buf) - strlen(buf)); p = buf; - comboLine = strdup(p+5); // [HGM] recent: remember complete line of first combobox + currentEngine[0] = strdup(p+5); // [HGM] recent: remember complete line of first combobox ParseArgs(StringGet, &p); safeStrCpy(buf, singleList ? "/fcp=" : "/scp=", sizeof(buf)/sizeof(buf[0]) ); GetDlgItemText(hDlg, OPT_SecondChessEngineName, buf + strlen(buf), sizeof(buf) - strlen(buf)); p = buf; + currentEngine[1] = strdup(p+5); // [HGM] also remember engine line of 2nd for saving its settings SwapEngines(singleList); // temporarily swap first and second, to load a second 'first', ... ParseArgs(StringGet, &p); SwapEngines(singleList); // ... and then make it 'second' @@ -6714,7 +6826,7 @@ TypeInNameDialog(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) case IDOK: GetDlgItemText(hDlg, OPT_Name, move, sizeof(move)); appData.userName = strdup(move); - SetUserLogo(); + SetUserLogo(); DisplayLogos(); SetGameInfo(); if(gameMode == MachinePlaysWhite || gameMode == MachinePlaysBlack) { snprintf(move, MSG_SIZ, "%s vs. %s", gameInfo.white, gameInfo.black); @@ -7670,6 +7782,7 @@ DisplayAClock(HDC hdc, int timeRemaining, int highlight, oldFg = SetTextColor(hdc, RGB(0, 0, 0)); /* black */ oldBg = SetBkColor(hdc, RGB(255, 255, 255)); /* white */ } + oldFont = SelectObject(hdc, font[boardSize][CLOCK_FONT]->hf); JAWS_SILENCE @@ -7986,6 +8099,7 @@ Enables gnuEnables[] = { { IDM_Annotate, MF_BYCOMMAND|MF_GRAYED }, { IDM_NewChat, MF_BYCOMMAND|MF_GRAYED }, + // Needed to switch from ncp to GNU mode on Engine Load { ACTION_POS, MF_BYPOSITION|MF_ENABLED }, { IDM_MachineWhite, MF_BYCOMMAND|MF_ENABLED }, @@ -8215,6 +8329,8 @@ ModeHighlight() nowChecked = 0; break; } + if(prevChecked == IDM_TwoMachines) // [HGM] 'Machine Match' might have gotten disabled when stopping match + EnableMenuItem(GetMenu(hwndMain), IDM_Match, MF_BYCOMMAND|MF_ENABLED); CheckMark(prevChecked, MF_UNCHECKED); CheckMark(nowChecked, MF_CHECKED); CheckMark(IDM_Match, matchMode && matchGame < appData.matchGames ? MF_CHECKED : MF_UNCHECKED); @@ -8459,6 +8575,7 @@ DisplayFatalError(char *str, int error, int exitStatus) fprintf(debugFP, "%s: %s\n", label, str); } if (appData.popupExitMessage) { + if(appData.icsActive) SendToICS("logout\n"); // [HGM] make sure no new games will be started! (void) MessageBox(hwndMain, str, label, MB_OK| (exitStatus ? MB_ICONSTOP : MB_ICONINFORMATION)); } @@ -8472,6 +8589,11 @@ DisplayInformation(char *str) (void) MessageBox(hwndMain, str, _("Information"), MB_OK|MB_ICONINFORMATION); } +char * +Shorten (char *s) +{ + return s; +} VOID DisplayNote(char *str) @@ -8754,7 +8876,7 @@ DisplayIcsInteractionTitle(char *str) } void -DrawPosition(int fullRedraw, Board board) +DrawPositionX(int fullRedraw, Board board) { HDCDrawPosition(NULL, (BOOLEAN) fullRedraw, board); } @@ -9081,6 +9203,7 @@ IDLE_PRIORITY_CLASS 0x00000040 */ if (nice < -15) return 0x00000080; if (nice < 0) return 0x00008000; + if (nice == 0) return 0x00000020; if (nice < 15) return 0x00004000; return 0x00000040; @@ -9559,6 +9682,7 @@ OpenRcmd(char* host, char* user, char* cmd, ProcRef* pr) return WSAEADDRINUSE; } if (s == INVALID_SOCKET) { + if ((s = socket(PF_INET, SOCK_STREAM, 0)) == INVALID_SOCKET) { err = WSAGetLastError(); WSACleanup(); @@ -9991,8 +10115,8 @@ AnimateMove(board, fromX, fromY, toX, toY) int toX; int toY; { - ChessSquare piece; - int x = toX, y = toY; + ChessSquare piece, victim = EmptySquare, victim2 = EmptySquare; + int x = toX, y = toY, x2 = kill2X; POINT start, finish, mid; POINT frames[kFactor * 2 + 1]; int nFrames, n; @@ -10005,7 +10129,11 @@ AnimateMove(board, fromX, fromY, toX, toY) piece = board[fromY][fromX]; if (piece >= EmptySquare) return; - if(killX >= 0) toX = killX, toY = killY; // [HGM] lion: first to kill square + if(x2 >= 0) toX = kill2X, toY = kill2Y, victim = board[killY][killX], victim2 = board[kill2Y][kill2X]; else + if(killX >= 0) toX = killX, toY = killY, victim = board[killY][killX]; // [HGM] lion: first to kill square + + animInfo.from.x = fromX; + animInfo.from.y = fromY; again: @@ -10033,22 +10161,30 @@ again: else Tween(&start, &mid, &finish, kFactor, frames, &nFrames); - animInfo.from.x = fromX; - animInfo.from.y = fromY; animInfo.to.x = toX; animInfo.to.y = toY; animInfo.lastpos = start; animInfo.piece = piece; for (n = 0; n < nFrames; n++) { animInfo.pos = frames[n]; - DrawPosition(FALSE, NULL); + DrawPosition(FALSE, board); animInfo.lastpos = animInfo.pos; Sleep(appData.animSpeed); } animInfo.pos = finish; - DrawPosition(FALSE, NULL); - - if(toX != x || toY != y) { fromX = toX; fromY = toY; toX = x; toY = y; goto again; } // second leg + DrawPosition(FALSE, board); + + if(toX == x2 && toY == kill2Y) { + fromX = toX; fromY = toY; toX = killX; toY = killY; x2 = -1; + board[kill2Y][kill2X] = EmptySquare; goto again; + } // second leg + if(toX != x || toY != y) { + fromX = toX; fromY = toY; toX = x; toY = y; + board[killY][killX] = EmptySquare; goto again; + } // second leg + +if(victim2 != EmptySquare) board[kill2Y][kill2X] = victim2; +if(victim != EmptySquare) board[killY][killX] = victim; animInfo.piece = EmptySquare; Explode(board, fromX, fromY, toX, toY);