X-Git-Url: http://winboard.nl/cgi-bin?a=blobdiff_plain;f=winboard%2Fwinboard.c;h=fb64ff7f8448ca14613e18930600658a8908390d;hb=ea750683ac62717dd7346de17b5ae072622ff92a;hp=139a984a8f7c0ef2fca278ee80dc40a78d902720;hpb=86517e539f33650be656c482020a878fec0723c9;p=xboard.git diff --git a/winboard/winboard.c b/winboard/winboard.c index 139a984..fb64ff7 100644 --- a/winboard/winboard.c +++ b/winboard/winboard.c @@ -86,7 +86,7 @@ #include "wsnap.h" -void InitEngineUCI( const char * iniDir, ChessProgramState * cps ); +//void InitEngineUCI( const char * iniDir, ChessProgramState * cps ); int myrandom(void); void mysrandom(unsigned int seed); @@ -140,7 +140,8 @@ BOOLEAN chessProgram; static int boardX, boardY, consoleX, consoleY, consoleW, consoleH; static int squareSize, lineGap, minorSize; static int winWidth, winHeight; -static RECT messageRect, whiteRect, blackRect; +static RECT messageRect, whiteRect, blackRect, leftLogoRect, rightLogoRect; // [HGM] logo +static int logoHeight = 0; static char messageText[MESSAGE_TEXT_MAX]; static int clockTimerEvent = 0; static int loadGameTimerEvent = 0; @@ -598,8 +599,8 @@ InitInstance(HINSTANCE hInstance, int nCmdShow, LPSTR lpCmdLine) InitBackEnd1(); - InitEngineUCI( installDir, &first ); - InitEngineUCI( installDir, &second ); +// InitEngineUCI( installDir, &first ); // [HGM] incorporated in InitBackEnd1() +// InitEngineUCI( installDir, &second ); /* Create a main window for this application instance. */ hwnd = CreateWindow(szAppName, szTitle, @@ -613,6 +614,35 @@ InitInstance(HINSTANCE hInstance, int nCmdShow, LPSTR lpCmdLine) return (FALSE); } + /* [HGM] logo: Load logos if specified (must be done before InitDrawingSizes) */ + if( appData.firstLogo && appData.firstLogo[0] != NULLCHAR) { + first.programLogo = LoadImage( 0, appData.firstLogo, IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE ); + + if (first.programLogo == NULL && appData.debugMode) { + fprintf( debugFP, "Unable to load logo bitmap '%s'\n", appData.firstLogo ); + } + } else if(appData.autoLogo) { + if(appData.firstDirectory && appData.firstDirectory[0]) { + char buf[MSG_SIZ]; + sprintf(buf, "%s/logo.bmp", appData.firstDirectory); + first.programLogo = LoadImage( 0, buf, IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE ); + } + } + + if( appData.secondLogo && appData.secondLogo[0] != NULLCHAR) { + second.programLogo = LoadImage( 0, appData.secondLogo, IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE ); + + if (second.programLogo == NULL && appData.debugMode) { + fprintf( debugFP, "Unable to load logo bitmap '%s'\n", appData.secondLogo ); + } + } else if(appData.autoLogo) { + if(appData.secondDirectory && appData.secondDirectory[0]) { + char buf[MSG_SIZ]; + sprintf(buf, "%s\\logo.bmp", appData.secondDirectory); + second.programLogo = LoadImage( 0, buf, IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE ); + } + } + iconWhite = LoadIcon(hInstance, "icon_white"); iconBlack = LoadIcon(hInstance, "icon_black"); iconCurrent = iconWhite; @@ -630,6 +660,7 @@ InitInstance(HINSTANCE hInstance, int nCmdShow, LPSTR lpCmdLine) boardSize = (BoardSize)ibs; } } + InitDrawingSizes(boardSize, 0); InitMenuChecks(); buttonCount = GetSystemMetrics(SM_CMOUSEBUTTONS); @@ -657,11 +688,6 @@ InitInstance(HINSTANCE hInstance, int nCmdShow, LPSTR lpCmdLine) mysrandom( (unsigned) time(NULL) ); - /* Make a console window if needed */ - if (appData.icsActive) { - ConsoleCreate(); - } - /* [AS] Restore layout */ if( wpMoveHistory.visible ) { MoveHistoryPopUp(); @@ -1173,6 +1199,8 @@ ArgDescriptor argDescriptors[] = { { "flipBlack", ArgBoolean, (LPVOID) &appData.upsideDown, TRUE }, { "allWhite", ArgBoolean, (LPVOID) &appData.allWhite, TRUE }, { "alphaRank", ArgBoolean, (LPVOID) &appData.alphaRank, FALSE }, + { "firstAlphaRank", ArgBoolean, (LPVOID) &first.alphaRank, FALSE }, + { "secondAlphaRank", ArgBoolean, (LPVOID) &second.alphaRank, FALSE }, { "testClaims", ArgBoolean, (LPVOID) &appData.testClaims, TRUE }, { "checkMates", ArgBoolean, (LPVOID) &appData.checkMates, TRUE }, { "materialDraws", ArgBoolean, (LPVOID) &appData.materialDraws, TRUE }, @@ -1182,6 +1210,14 @@ ArgDescriptor argDescriptors[] = { { "autoKibitz", ArgTrue, (LPVOID) &appData.autoKibitz, FALSE }, { "engineDebugOutput", ArgInt, (LPVOID) &appData.engineComments, FALSE }, { "userName", ArgString, (LPVOID) &appData.userName, FALSE }, + { "rewindIndex", ArgInt, (LPVOID) &appData.rewindIndex, FALSE }, + { "sameColorGames", ArgInt, (LPVOID) &appData.sameColorGames, FALSE }, + { "smpCores", ArgInt, (LPVOID) &appData.smpCores, TRUE }, + { "egtFormats", ArgString, (LPVOID) &appData.egtFormats, TRUE }, + { "niceEngines", ArgInt, (LPVOID) &appData.niceEngines, TRUE }, + { "firstLogo", ArgFilename, (LPVOID) &appData.firstLogo, FALSE }, + { "secondLogo", ArgFilename, (LPVOID) &appData.secondLogo, FALSE }, + { "autoLogo", ArgBoolean, (LPVOID) &appData.autoLogo, TRUE }, #ifdef ZIPPY { "zippyTalk", ArgBoolean, (LPVOID) &appData.zippyTalk, FALSE }, @@ -1236,6 +1272,7 @@ ArgDescriptor argDescriptors[] = { { "secondAccumulateTC", ArgInt, (LPVOID) &appData.secondAccumulateTC, FALSE }, { "firstNPS", ArgInt, (LPVOID) &appData.firstNPS, FALSE }, { "secondNPS", ArgInt, (LPVOID) &appData.secondNPS, FALSE }, + { "noGUI", ArgTrue, (LPVOID) &appData.noGUI, FALSE }, { NULL, ArgNone, NULL, FALSE } }; @@ -1797,6 +1834,7 @@ InitAppData(LPSTR lpCmdLine) appData.reuseFirst = TRUE; appData.reuseSecond = TRUE; appData.blindfold = FALSE; + appData.icsEngineAnalyze = FALSE; dcb.DCBlength = sizeof(DCB); dcb.BaudRate = 9600; dcb.fBinary = TRUE; @@ -1811,7 +1849,12 @@ InitAppData(LPSTR lpCmdLine) dcb.fNull = FALSE; dcb.fRtsControl = RTS_CONTROL_ENABLE; dcb.fAbortOnError = FALSE; - dcb.wReserved = 0; + /* Microsoft SDK >= Feb. 2003 (MS VS >= 2002) */ + #if (defined(_MSC_VER) && _MSC_VER <= 1200) + //dcb.wReserved = 0; + #else + dcb.wReserved = 0; + #endif dcb.ByteSize = 7; dcb.Parity = SPACEPARITY; dcb.StopBits = ONESTOPBIT; @@ -1922,7 +1965,8 @@ InitAppData(LPSTR lpCmdLine) appData.firstNPS = -1; // [HGM] nps: use wall-clock time appData.secondNPS = -1; appData.engineComments = 1; - + appData.smpCores = 1; // [HGM] SMP: max nr of cores + appData.egtFormats = ""; #ifdef ZIPPY appData.zippyTalk = ZIPPY_TALK; @@ -2365,6 +2409,12 @@ enum { PM_WH = (int) WhiteNightrider, PM_WA = (int) WhiteAngel, PM_WC = (int) WhiteMarshall, + PM_WAB = (int) WhiteCardinal, + PM_WD = (int) WhiteDragon, + PM_WL = (int) WhiteLance, + PM_WS = (int) WhiteCobra, + PM_WV = (int) WhiteFalcon, + PM_WSG = (int) WhiteSilver, PM_WG = (int) WhiteGrasshopper, PM_WK = (int) WhiteKing, PM_BP = (int) BlackPawn, @@ -2382,6 +2432,12 @@ enum { PM_BA = (int) BlackAngel, PM_BC = (int) BlackMarshall, PM_BG = (int) BlackGrasshopper, + PM_BAB = (int) BlackCardinal, + PM_BD = (int) BlackDragon, + PM_BL = (int) BlackLance, + PM_BS = (int) BlackCobra, + PM_BV = (int) BlackFalcon, + PM_BSG = (int) BlackSilver, PM_BK = (int) BlackKing }; @@ -2480,13 +2536,12 @@ static void CreatePieceMaskFromFont( HDC hdc_window, HDC hdc, int index ) POINT pt; int backColor = whitePieceColor; int foreColor = blackPieceColor; - int shapeIndex = index < 6 ? index+6 : index; - if( index < 6 && appData.fontBackColorWhite != appData.fontForeColorWhite ) { + if( index < (int)BlackPawn && appData.fontBackColorWhite != appData.fontForeColorWhite ) { backColor = appData.fontBackColorWhite; foreColor = appData.fontForeColorWhite; } - else if( index >= 6 && appData.fontBackColorBlack != appData.fontForeColorBlack ) { + else if( index >= (int)BlackPawn && appData.fontBackColorBlack != appData.fontForeColorBlack ) { backColor = appData.fontBackColorBlack; foreColor = appData.fontForeColorBlack; } @@ -2512,11 +2567,15 @@ static void CreatePieceMaskFromFont( HDC hdc_window, HDC hdc, int index ) SetBkMode( hdc, TRANSPARENT ); SetTextColor( hdc, chroma ); /* Step 2: the piece has been drawn in purple, there are now black and purple in this bitmap */ - TextOut( hdc, pt.x, pt.y, &pieceToFontChar[index], 1 ); + TextOut( hdc, pt.x, pt.y, &pieceToFontChar[appData.allWhite && index >= (int)BlackPawn ? index - (int)BlackPawn : index], 1 ); SelectObject( hdc, GetStockObject(WHITE_BRUSH) ); /* Step 3: the area outside the piece is filled with white */ - FloodFill( hdc, 0, 0, chroma ); +// FloodFill( hdc, 0, 0, chroma ); + ExtFloodFill( hdc, 0, 0, 0, FLOODFILLSURFACE ); + ExtFloodFill( hdc, 0, squareSize-1, 0, FLOODFILLSURFACE ); // [HGM] fill from all 4 corners, for if piece too big + ExtFloodFill( hdc, squareSize-1, 0, 0, FLOODFILLSURFACE ); + ExtFloodFill( hdc, squareSize-1, squareSize-1, 0, FLOODFILLSURFACE ); SelectObject( hdc, GetStockObject(BLACK_BRUSH) ); /* Step 4: this is the tricky part, the area inside the piece is filled with black, @@ -2524,14 +2583,30 @@ static void CreatePieceMaskFromFont( HDC hdc_window, HDC hdc, int index ) There should be a better way to do this... if we could create a region or path from the fill operation we would be fine for example. */ - FloodFill( hdc, squareSize / 2, squareSize / 2, RGB(0xFF,0xFF,0xFF) ); +// FloodFill( hdc, squareSize / 2, squareSize / 2, RGB(0xFF,0xFF,0xFF) ); + ExtFloodFill( hdc, squareSize / 2, squareSize / 2, RGB(0xFF,0xFF,0xFF), FLOODFILLBORDER ); + + { /* [HGM] shave off edges of mask, in an attempt to correct for the fact that FloodFill does not work correctly under Win XP */ + HDC dc2 = CreateCompatibleDC( hdc_window ); + HBITMAP bm2 = CreateCompatibleBitmap( hdc_window, squareSize, squareSize ); + + SelectObject( dc2, bm2 ); + BitBlt( dc2, 0, 0, squareSize, squareSize, hdc, 0, 0, SRCCOPY ); // make copy + BitBlt( hdc, 0, 1, squareSize-2, squareSize-2, dc2, 1, 1, SRCPAINT ); + BitBlt( hdc, 2, 1, squareSize-2, squareSize-2, dc2, 1, 1, SRCPAINT ); + BitBlt( hdc, 1, 0, squareSize-2, squareSize-2, dc2, 1, 1, SRCPAINT ); + BitBlt( hdc, 1, 2, squareSize-2, squareSize-2, dc2, 1, 1, SRCPAINT ); + + DeleteDC( dc2 ); + DeleteObject( bm2 ); + } SetTextColor( hdc, 0 ); /* Step 5: some fonts have "disconnected" areas that are skipped by the fill: draw the piece again in black for safety. */ - TextOut( hdc, pt.x, pt.y, &pieceToFontChar[index], 1 ); + TextOut( hdc, pt.x, pt.y, &pieceToFontChar[appData.allWhite && index >= (int)BlackPawn ? index - (int)BlackPawn : index], 1 ); SelectObject( hdc, hbm_old ); @@ -2572,7 +2647,7 @@ static void CreatePieceMaskFromFont( HDC hdc_window, HDC hdc, int index ) } SetTextColor( hdc, foreColor ); - TextOut( hdc, pt.x, pt.y, &pieceToFontChar[index], 1 ); + TextOut( hdc, pt.x, pt.y, &pieceToFontChar[appData.allWhite && index >= (int)BlackPawn ? index - (int)BlackPawn : index], 1 ); SelectObject( hdc, hbm_old ); @@ -2610,6 +2685,7 @@ static int TranslatePieceToFontPiece( int piece ) return PM_WQ; case WhiteKing: return PM_WK; + case BlackAngel: return PM_BA; case BlackMarshall: @@ -2630,6 +2706,19 @@ static int TranslatePieceToFontPiece( int piece ) return PM_BG; case BlackMan: return PM_BM; + case BlackSilver: + return PM_BSG; + case BlackLance: + return PM_BL; + case BlackFalcon: + return PM_BV; + case BlackCobra: + return PM_BS; + case BlackCardinal: + return PM_BAB; + case BlackDragon: + return PM_BD; + case WhiteAngel: return PM_WA; case WhiteMarshall: @@ -2650,6 +2739,18 @@ static int TranslatePieceToFontPiece( int piece ) return PM_WG; case WhiteMan: return PM_WM; + case WhiteSilver: + return PM_WSG; + case WhiteLance: + return PM_WL; + case WhiteFalcon: + return PM_WV; + case WhiteCobra: + return PM_WS; + case WhiteCardinal: + return PM_WAB; + case WhiteDragon: + return PM_WD; } return 0; @@ -2682,7 +2783,7 @@ void CreatePiecesFromFont() DeleteObject( hPieceFont ); } else { - for( i=0; i<12; i++ ) { + for( i=0; i<=(int)BlackKing; i++ ) { hPieceMask[i] = NULL; hPieceFace[i] = NULL; } @@ -2747,7 +2848,7 @@ void CreatePiecesFromFont() /* Create bitmaps */ hfont_old = SelectObject( hdc, hPieceFont ); - +#if 0 CreatePieceMaskFromFont( hdc_window, hdc, PM_WP ); CreatePieceMaskFromFont( hdc_window, hdc, PM_WN ); CreatePieceMaskFromFont( hdc_window, hdc, PM_WB ); @@ -2760,7 +2861,7 @@ void CreatePiecesFromFont() CreatePieceMaskFromFont( hdc_window, hdc, PM_BR ); CreatePieceMaskFromFont( hdc_window, hdc, PM_BQ ); CreatePieceMaskFromFont( hdc_window, hdc, PM_BK ); -#ifdef FAIRY + CreatePieceMaskFromFont( hdc_window, hdc, PM_WA ); CreatePieceMaskFromFont( hdc_window, hdc, PM_WC ); CreatePieceMaskFromFont( hdc_window, hdc, PM_WF ); @@ -2771,6 +2872,12 @@ void CreatePiecesFromFont() CreatePieceMaskFromFont( hdc_window, hdc, PM_WO ); CreatePieceMaskFromFont( hdc_window, hdc, PM_WG ); CreatePieceMaskFromFont( hdc_window, hdc, PM_WM ); + CreatePieceMaskFromFont( hdc_window, hdc, PM_WSG ); + CreatePieceMaskFromFont( hdc_window, hdc, PM_WV ); + CreatePieceMaskFromFont( hdc_window, hdc, PM_WAB ); + CreatePieceMaskFromFont( hdc_window, hdc, PM_WD ); + CreatePieceMaskFromFont( hdc_window, hdc, PM_WL ); + CreatePieceMaskFromFont( hdc_window, hdc, PM_WS ); CreatePieceMaskFromFont( hdc_window, hdc, PM_BA ); CreatePieceMaskFromFont( hdc_window, hdc, PM_BC ); CreatePieceMaskFromFont( hdc_window, hdc, PM_BF ); @@ -2781,8 +2888,17 @@ void CreatePiecesFromFont() CreatePieceMaskFromFont( hdc_window, hdc, PM_BO ); CreatePieceMaskFromFont( hdc_window, hdc, PM_BG ); CreatePieceMaskFromFont( hdc_window, hdc, PM_BM ); + CreatePieceMaskFromFont( hdc_window, hdc, PM_BSG ); + CreatePieceMaskFromFont( hdc_window, hdc, PM_BV ); + CreatePieceMaskFromFont( hdc_window, hdc, PM_BAB ); + CreatePieceMaskFromFont( hdc_window, hdc, PM_BD ); + CreatePieceMaskFromFont( hdc_window, hdc, PM_BL ); + CreatePieceMaskFromFont( hdc_window, hdc, PM_BS ); +#else + for(i=(int)WhitePawn; i<(int)EmptySquare; i++) /* [HGM] made a loop for this */ + if(PieceToChar((ChessSquare)i) != '.') /* skip unused pieces */ + CreatePieceMaskFromFont( hdc_window, hdc, i ); #endif - SelectObject( hdc, hfont_old ); fontBitmapSquareSize = squareSize; @@ -2900,9 +3016,10 @@ ResizeBoard(int newSizeX, int newSizeY, int flags) if (IsIconic(hwndMain)) return; if (recurse > 0) return; recurse++; - while (newSize > 0 && - (newSizeX < sizeInfo[newSize].cliWidth || - newSizeY < sizeInfo[newSize].cliHeight)) { + while (newSize > 0) { + InitDrawingSizes(newSize, 0); + if(newSizeX >= sizeInfo[newSize].cliWidth || + newSizeY >= sizeInfo[newSize].cliHeight) break; newSize--; } boardSize = newSize; @@ -2979,27 +3096,52 @@ InitDrawingSizes(BoardSize boardSize, int flags) ReleaseDC(hwndMain, hdc); /* Compute where everything goes */ - whiteRect.left = OUTER_MARGIN; - whiteRect.right = whiteRect.left + boardWidth/2 - INNER_MARGIN/2; - whiteRect.top = OUTER_MARGIN; - whiteRect.bottom = whiteRect.top + clockSize.cy; + if(first.programLogo || second.programLogo) { + /* [HGM] logo: if either logo is on, reserve space for it */ + logoHeight = 2*clockSize.cy; + leftLogoRect.left = OUTER_MARGIN; + leftLogoRect.right = leftLogoRect.left + 4*clockSize.cy; + leftLogoRect.top = OUTER_MARGIN; + leftLogoRect.bottom = OUTER_MARGIN + logoHeight; + + rightLogoRect.right = OUTER_MARGIN + boardWidth; + rightLogoRect.left = rightLogoRect.right - 4*clockSize.cy; + rightLogoRect.top = OUTER_MARGIN; + rightLogoRect.bottom = OUTER_MARGIN + logoHeight; + + + blackRect.left = leftLogoRect.right; + blackRect.right = rightLogoRect.left; + blackRect.top = OUTER_MARGIN; + blackRect.bottom = blackRect.top + clockSize.cy; + + whiteRect.left = blackRect.left ; + whiteRect.right = blackRect.right; + whiteRect.top = blackRect.bottom; + whiteRect.bottom = leftLogoRect.bottom; + } else { + whiteRect.left = OUTER_MARGIN; + whiteRect.right = whiteRect.left + boardWidth/2 - INNER_MARGIN/2; + whiteRect.top = OUTER_MARGIN + logoHeight; + whiteRect.bottom = whiteRect.top + clockSize.cy; - blackRect.left = whiteRect.right + INNER_MARGIN; - blackRect.right = blackRect.left + boardWidth/2 - 1; - blackRect.top = whiteRect.top; - blackRect.bottom = whiteRect.bottom; + blackRect.left = whiteRect.right + INNER_MARGIN; + blackRect.right = blackRect.left + boardWidth/2 - 1; + blackRect.top = whiteRect.top; + blackRect.bottom = whiteRect.bottom; + } - messageRect.left = whiteRect.left + MESSAGE_LINE_LEFTMARGIN; + messageRect.left = OUTER_MARGIN + MESSAGE_LINE_LEFTMARGIN; if (appData.showButtonBar) { - messageRect.right = blackRect.right + messageRect.right = OUTER_MARGIN + boardWidth // [HGM] logo: expressed independent of clock placement - N_BUTTONS*BUTTON_WIDTH - MESSAGE_LINE_LEFTMARGIN; } else { - messageRect.right = blackRect.right; + messageRect.right = OUTER_MARGIN + boardWidth; } messageRect.top = whiteRect.bottom + INNER_MARGIN; messageRect.bottom = messageRect.top + messageSize.cy; - boardRect.left = whiteRect.left; + boardRect.left = OUTER_MARGIN; boardRect.right = boardRect.left + boardWidth; boardRect.top = messageRect.bottom + INNER_MARGIN; boardRect.bottom = boardRect.top + boardHeight; @@ -3135,6 +3277,7 @@ InitDrawingSizes(BoardSize boardSize, int flags) } } + 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"); @@ -3484,7 +3627,7 @@ DrawPieceOnDC(HDC hdc, ChessSquare piece, int color, int sqcolor, int x, int y, CreatePiecesFromFont(); if( fontBitmapSquareSize == squareSize ) { - int index = TranslatePieceToFontPiece( piece ); + int index = TranslatePieceToFontPiece(piece); SelectObject( tmphdc, hPieceMask[ index ] ); @@ -3629,16 +3772,16 @@ VOID RebuildTextureSquareInfo() if( (col + row) & 1 ) { /* Lite square */ if( lite_w >= squareSize && lite_h >= squareSize ) { - backTextureSquareInfo[row][col].x = col * (lite_w - squareSize) / BOARD_WIDTH; - backTextureSquareInfo[row][col].y = row * (lite_h - squareSize) / BOARD_HEIGHT; + backTextureSquareInfo[row][col].x = col * (lite_w - squareSize) / (BOARD_WIDTH-1); /* [HGM] divide by size-1 in stead of size! */ + backTextureSquareInfo[row][col].y = (BOARD_HEIGHT-1-row) * (lite_h - squareSize) / (BOARD_HEIGHT-1); backTextureSquareInfo[row][col].mode = GetBackTextureMode(liteBackTextureMode); } } else { /* Dark square */ if( dark_w >= squareSize && dark_h >= squareSize ) { - backTextureSquareInfo[row][col].x = col * (dark_w - squareSize) / BOARD_WIDTH; - backTextureSquareInfo[row][col].y = row * (dark_h - squareSize) / BOARD_HEIGHT; + backTextureSquareInfo[row][col].x = col * (dark_w - squareSize) / (BOARD_WIDTH-1); + backTextureSquareInfo[row][col].y = (BOARD_HEIGHT-1-row) * (dark_h - squareSize) / (BOARD_HEIGHT-1); backTextureSquareInfo[row][col].mode = GetBackTextureMode(darkBackTextureMode); } } @@ -3945,7 +4088,10 @@ DrawBoardOnDC(HDC hdc, Board board, HDC tmphdc) /* [AS] Initialize background textures if needed */ if( liteBackTexture != NULL || darkBackTexture != NULL ) { - if( backTextureSquareSize != squareSize ) { + static int backTextureBoardSize; /* [HGM] boardsize: also new texture if board format changed */ + if( backTextureSquareSize != squareSize + || backTextureBoardSize != BOARD_WIDTH+BOARD_SIZE*BOARD_HEIGHT) { + backTextureBoardSize = BOARD_WIDTH+BOARD_SIZE*BOARD_HEIGHT; backTextureSquareSize = squareSize; RebuildTextureSquareInfo(); } @@ -3961,7 +4107,7 @@ DrawBoardOnDC(HDC hdc, Board board, HDC tmphdc) piece = board[row][column]; square_color = ((column + row) % 2) == 1; - if(!strcmp(appData.variant, "xiangqi") ) { + if( gameInfo.variant == VariantXiangqi ) { square_color = !InPalace(row, column); if(BOARD_HEIGHT&1) { if(row==BOARD_HEIGHT/2) square_color ^= 1; } else if(row < BOARD_HEIGHT/2) square_color ^= 1; @@ -3987,9 +4133,9 @@ DrawBoardOnDC(HDC hdc, Board board, HDC tmphdc) } } if(column == BOARD_LEFT-1 ) /* left align */ - DisplayHoldingsCount(hdc, x, y, 0, (int) board[row][column]); + DisplayHoldingsCount(hdc, x, y, flipView, (int) board[row][column]); else if( column == BOARD_RGHT) /* right align */ - DisplayHoldingsCount(hdc, x, y, 1, (int) board[row][column]); + DisplayHoldingsCount(hdc, x, y, !flipView, (int) board[row][column]); else if (appData.monoMode) { if (piece == EmptySquare) { @@ -4002,14 +4148,16 @@ DrawBoardOnDC(HDC hdc, Board board, HDC tmphdc) else if( backTextureSquareInfo[row][column].mode > 0 ) { /* [AS] Draw the square using a texture bitmap */ HBITMAP hbm = SelectObject( texture_hdc, square_color ? liteBackTexture : darkBackTexture ); + int r = row, c = column; // [HGM] do not flip board in flipView + if(flipView) { r = BOARD_HEIGHT-1 - r; c = BOARD_WIDTH-1 - c; } DrawTile( x, y, squareSize, squareSize, hdc, texture_hdc, - backTextureSquareInfo[row][column].mode, - backTextureSquareInfo[row][column].x, - backTextureSquareInfo[row][column].y ); + backTextureSquareInfo[r][c].mode, + backTextureSquareInfo[r][c].x, + backTextureSquareInfo[r][c].y ); SelectObject( texture_hdc, hbm ); @@ -4046,6 +4194,32 @@ void fputDW(FILE *f, int x) #define MAX_CLIPS 200 /* more than enough */ VOID +DrawLogoOnDC(HDC hdc, RECT logoRect, ChessProgramState *cps) +{ + HBITMAP bufferBitmap; + BITMAP bi; + RECT Rect; + HDC tmphdc; + HBITMAP hbm; + int w = 100, h = 50; + + if(cps->programLogo == NULL) return; +// GetClientRect(hwndMain, &Rect); +// bufferBitmap = CreateCompatibleBitmap(hdc, Rect.right-Rect.left+1, +// Rect.bottom-Rect.top+1); + tmphdc = CreateCompatibleDC(hdc); + hbm = SelectObject(tmphdc, (HBITMAP) cps->programLogo); + if( GetObject( cps->programLogo, sizeof(bi), &bi ) > 0 ) { + w = bi.bmWidth; + h = bi.bmHeight; + } + StretchBlt(hdc, logoRect.left, logoRect.top, logoRect.right - logoRect.left, + logoRect.bottom - logoRect.top, tmphdc, 0, 0, w, h, SRCCOPY); + SelectObject(tmphdc, hbm); + DeleteDC(tmphdc); +} + +VOID HDCDrawPosition(HDC hdc, BOOLEAN repaint, Board board) { static Board lastReq, lastDrawn; @@ -4299,6 +4473,11 @@ HDCDrawPosition(HDC hdc, BOOLEAN repaint, Board board) DrawHighlightsOnDC(hdcmem); DrawBoardOnDC(hdcmem, board, tmphdc); + if(logoHeight) { + DrawLogoOnDC(hdc, leftLogoRect, flipClock ? &second : &first); + DrawLogoOnDC(hdc, rightLogoRect, flipClock ? &first : &second); + } + if( appData.highlightMoveWithArrow ) { DrawArrowHighlight(hdcmem); } @@ -4357,7 +4536,6 @@ HDCDrawPosition(HDC hdc, BOOLEAN repaint, Board board) boardRect.right - boardRect.left, boardRect.bottom - boardRect.top, tmphdc, boardRect.left, boardRect.top, SRCCOPY); - if(saveDiagFlag) { BITMAP b; int i, j, m, w, wb, fac=0; char pData[1000000]; BITMAPINFOHEADER bih; int color[16], nrColors=0; @@ -4586,7 +4764,7 @@ MouseEvent(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) BOOLEAN needsRedraw = FALSE; BOOLEAN saveAnimate; BOOLEAN forceFullRepaint = IsFullRepaintPreferrable(); /* [AS] */ - static BOOLEAN sameAgain = FALSE; + static BOOLEAN sameAgain = FALSE, promotionChoice = FALSE; ChessMove moveType; if (recursive) { @@ -4614,6 +4792,25 @@ MouseEvent(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) switch (message) { case WM_LBUTTONDOWN: + if(promotionChoice) { // we are waiting for a click to indicate promotion piece + promotionChoice = FALSE; // only one chance: if click not OK it is interpreted as cancel + if(appData.debugMode) fprintf(debugFP, "promotion click, x=%d, y=%d\n", x, y); + if(gameInfo.holdingsWidth && + (WhiteOnMove(currentMove) + ? x == BOARD_WIDTH-1 && y < gameInfo.holdingsSize && y > 0 + : x == 0 && y >= BOARD_HEIGHT - gameInfo.holdingsSize && y < BOARD_HEIGHT-1) ) { + // click in right holdings, for determining promotion piece + ChessSquare p = boards[currentMove][y][x]; + if(appData.debugMode) fprintf(debugFP, "square contains %d\n", (int)p); + if(p != EmptySquare) { + FinishMove(WhitePromotionQueen, fromX, fromY, toX, toY, ToLower(PieceToChar(p))); + fromX = fromY = -1; + break; + } + } + DrawPosition(FALSE, boards[currentMove]); + break; + } ErrorPopDown(); sameAgain = FALSE; if (y == -2) { @@ -4625,7 +4822,7 @@ MouseEvent(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) gameMode == MachinePlaysWhite) { CallFlagEvent(); } else if (gameMode == EditGame) { - AdjustClock(flipClock, -1); + AdjustClock((logoHeight > 0 ? flipView: flipClock), -1); } } else if (PtInRect((LPRECT) &blackRect, pt)) { if (gameMode == EditPosition) { @@ -4634,7 +4831,7 @@ MouseEvent(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) gameMode == MachinePlaysBlack) { CallFlagEvent(); } else if (gameMode == EditGame) { - AdjustClock(!flipClock, -1); + AdjustClock(!(logoHeight > 0 ? flipView: flipClock), -1); } } if (!appData.highlightLastMove) { @@ -4670,6 +4867,12 @@ MouseEvent(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) /* [HGM] UserMoveEvent requires two calls now, to make sure move is legal before showing promotion popup */ moveType = UserMoveTest(fromX, fromY, toX, toY, NULLCHAR); + if(moveType == AmbiguousMove) { /* [HGM] Edit-Position move executed */ + fromX = fromY = -1; + ClearHighlights(); + DrawPosition(FALSE, boards[currentMove]); + break; + } else if(moveType != ImpossibleMove) { /* [HGM] We use PromotionToKnight in Shogi to indicate frorced promotion */ if (moveType == WhitePromotionKnight || moveType == BlackPromotionKnight || @@ -4686,6 +4889,16 @@ MouseEvent(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) DrawPosition(forceFullRepaint || FALSE, NULL); /* [HGM] Popup calls FinishMove now. If promotion to Q is legal, all are legal! */ + if(gameInfo.variant == VariantSuper || gameInfo.variant == VariantGreat) + { ChessSquare p = boards[currentMove][fromY][fromX], q = boards[currentMove][toY][toX]; + // kludge to temporarily execute move on display, wthout promotng yet + promotionChoice = TRUE; + boards[currentMove][fromY][fromX] = EmptySquare; // move Pawn to 8th rank + boards[currentMove][toY][toX] = p; + DrawPosition(FALSE, boards[currentMove]); + boards[currentMove][fromY][fromX] = p; // take back, but display stays + boards[currentMove][toY][toX] = q; + } else PromotionPopup(hwnd); } else { /* not a promotion */ if (appData.animate || appData.highlightLastMove) { @@ -4694,6 +4907,7 @@ MouseEvent(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) ClearHighlights(); } FinishMove(moveType, fromX, fromY, toX, toY, NULLCHAR); + fromX = fromY = -1; if (appData.animate && !appData.highlightLastMove) { ClearHighlights(); DrawPosition(forceFullRepaint || FALSE, NULL); @@ -4758,6 +4972,12 @@ MouseEvent(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) saveAnimate = appData.animate; /* sorry, Hawk :) */ appData.animate = appData.animate && !appData.animateDragging; moveType = UserMoveTest(fromX, fromY, toX, toY, NULLCHAR); + if(moveType == AmbiguousMove) { /* [HGM] Edit-Position move executed */ + fromX = fromY = -1; + ClearHighlights(); + DrawPosition(FALSE, boards[currentMove]); + break; + } else if(moveType != ImpossibleMove) { /* [HGM] use move type to determine if move is promotion. Knight is Shogi kludge for mandatory promotion, Queen means choice */ @@ -4768,6 +4988,17 @@ MouseEvent(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) else if (moveType == WhitePromotionQueen || moveType == BlackPromotionQueen ) { DrawPosition(forceFullRepaint || FALSE, NULL); + if(gameInfo.variant == VariantSuper || gameInfo.variant == VariantGreat) + { ChessSquare p = boards[currentMove][fromY][fromX], q = boards[currentMove][toY][toX]; + // kludge to temporarily execute move on display, wthout promotng yet + promotionChoice = TRUE; + boards[currentMove][fromY][fromX] = EmptySquare; // move Pawn to 8th rank + boards[currentMove][toY][toX] = p; + DrawPosition(FALSE, boards[currentMove]); + boards[currentMove][fromY][fromX] = p; // take back, but display stays + boards[currentMove][toY][toX] = q; + break; + } else PromotionPopup(hwnd); /* [HGM] Popup now calls FinishMove */ } else FinishMove(moveType, fromX, fromY, toX, toY, NULLCHAR); } @@ -4810,6 +5041,17 @@ MouseEvent(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) } break; + case WM_MOUSEWHEEL: // [DM] + /* Mouse Wheel is being rolled forward + * Play moves forward + */ + if((short)HIWORD(wParam) > 0 && currentMove < forwardMostMove) ForwardEvent(); + /* Mouse Wheel is being rolled backward + * Play moves backward + */ + if((short)HIWORD(wParam) < 0 && currentMove > backwardMostMove) BackwardEvent(); + break; + case WM_MBUTTONDOWN: case WM_RBUTTONDOWN: ErrorPopDown(); @@ -4825,9 +5067,9 @@ MouseEvent(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) if(y == -2) { /* [HGM] right mouse button in clock area edit-game mode ups clock */ if (PtInRect((LPRECT) &whiteRect, pt)) { - if (gameMode == EditGame) AdjustClock(flipClock, 1); + if (gameMode == EditGame) AdjustClock((logoHeight > 0 ? flipView: flipClock), 1); } else if (PtInRect((LPRECT) &blackRect, pt)) { - if (gameMode == EditGame) AdjustClock(!flipClock, 1); + if (gameMode == EditGame) AdjustClock(!(logoHeight > 0 ? flipView: flipClock), 1); } } DrawPosition(TRUE, NULL); @@ -4960,7 +5202,7 @@ Promotion(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) CenterWindow(hDlg, GetWindow(hDlg, GW_OWNER)); ShowWindow(GetDlgItem(hDlg, PB_King), (!appData.testLegality || gameInfo.variant == VariantSuicide || - gameInfo.variant == VariantGiveaway) ? + 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), @@ -4988,6 +5230,9 @@ Promotion(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) ShowWindow(GetDlgItem(hDlg, IDC_No), gameInfo.variant == VariantShogi ? SW_SHOW : SW_HIDE); + ShowWindow(GetDlgItem(hDlg, IDC_Centaur), + gameInfo.variant == VariantSuper ? + SW_SHOW : SW_HIDE); return TRUE; case WM_COMMAND: /* message: received a command */ @@ -4998,7 +5243,7 @@ Promotion(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) DrawPosition(FALSE, NULL); return TRUE; case PB_King: - promoChar = PieceToChar(BlackKing); + promoChar = gameInfo.variant == VariantSuper ? PieceToChar(BlackSilver) : PieceToChar(BlackKing); break; case PB_Queen: promoChar = gameInfo.variant == VariantShogi ? '+' : PieceToChar(BlackQueen); @@ -5052,7 +5297,8 @@ PromotionPopup(HWND hwnd) VOID ToggleShowThinking() { - ShowThinkingEvent(!appData.showThinking); + appData.showThinking = !appData.showThinking; + ShowThinkingEvent(); } VOID @@ -5140,6 +5386,7 @@ WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) FILE *f; UINT number; char fileTitle[MSG_SIZ]; + char buf[MSG_SIZ]; static SnapData sd; switch (message) { @@ -5164,6 +5411,7 @@ WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) case WM_MBUTTONUP: case WM_RBUTTONUP: case WM_MOUSEMOVE: + case WM_MOUSEWHEEL: MouseEvent(hwnd, message, wParam, lParam); break; @@ -5453,10 +5701,34 @@ WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) case IDM_AnalysisMode: if (!first.analysisSupport) { - char buf[MSG_SIZ]; sprintf(buf, "%s does not support analysis", first.tidy); DisplayError(buf, 0); } else { + /* [DM] icsEngineAnlyze [HGM] Why is this front-end??? */ + if (appData.icsActive) { + if (gameMode != IcsObserving) { + sprintf(buf, "You are not observing a game"); + DisplayError(buf, 0); + /* secure check */ + if (appData.icsEngineAnalyze) { + if (appData.debugMode) + fprintf(debugFP, "Found unexpected active ICS engine analyze \n"); + ExitAnalyzeMode(); + ModeHighlight(); + break; + } + break; + } else { + /* if enable, user want disable icsEngineAnalyze */ + if (appData.icsEngineAnalyze) { + ExitAnalyzeMode(); + ModeHighlight(); + break; + } + appData.icsEngineAnalyze = TRUE; + if (appData.debugMode) fprintf(debugFP, "ICS engine analyze starting...\n"); + } + } if (!appData.showThinking) ToggleShowThinking(); AnalyzeModeEvent(); } @@ -5922,8 +6194,8 @@ WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) AutoPlayGameLoop(); /* call into back end */ break; case ANALYSIS_TIMER_ID: - if ((gameMode == AnalyzeMode || gameMode == AnalyzeFile) && - appData.periodicUpdates) { + if ((gameMode == AnalyzeMode || gameMode == AnalyzeFile + || appData.icsEngineAnalyze) && appData.periodicUpdates) { AnalysisPeriodicEvent(0); } else { KillTimer(hwnd, analysisTimerEvent); @@ -5962,6 +6234,7 @@ WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) /* [AS] Snapping */ case WM_ENTERSIZEMOVE: + if(appData.debugMode) { fprintf(debugFP, "size-move\n"); } if (hwnd == hwndMain) { doingSizing = TRUE; lastSizing = 0; @@ -5970,15 +6243,18 @@ WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) break; case WM_SIZING: + if(appData.debugMode) { fprintf(debugFP, "sizing\n"); } if (hwnd == hwndMain) { lastSizing = wParam; } break; case WM_MOVING: + if(appData.debugMode) { fprintf(debugFP, "moving\n"); } return OnMoving( &sd, hwnd, wParam, lParam ); case WM_EXITSIZEMOVE: + if(appData.debugMode) { fprintf(debugFP, "exit size-move, size = %d\n", squareSize); } if (hwnd == hwndMain) { RECT client; doingSizing = FALSE; @@ -5986,6 +6262,7 @@ WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) GetClientRect(hwnd, &client); ResizeBoard(client.right, client.bottom, lastSizing); lastSizing = 0; + if(appData.debugMode) { fprintf(debugFP, "square size = %d\n", squareSize); } } return OnExitSizeMove( &sd, hwnd, wParam, lParam ); break; @@ -7678,6 +7955,26 @@ ConsoleWndProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) wp.rcNormalPosition.bottom = consoleY + consoleH; SetWindowPlacement(hDlg, &wp); } +#if 0 + // [HGM] Chessknight's change 2004-07-13 + else { /* Determine Defaults */ + WINDOWPLACEMENT wp; + consoleX = winWidth + 1; + consoleY = boardY; + consoleW = screenWidth - winWidth; + consoleH = winHeight; + EnsureOnScreen(&consoleX, &consoleY); + wp.length = sizeof(WINDOWPLACEMENT); + wp.flags = 0; + wp.showCmd = SW_SHOW; + wp.ptMaxPosition.x = wp.ptMaxPosition.y = 0; + wp.rcNormalPosition.left = consoleX; + wp.rcNormalPosition.right = consoleX + consoleW; + wp.rcNormalPosition.top = consoleY; + wp.rcNormalPosition.bottom = consoleY + consoleH; + SetWindowPlacement(hDlg, &wp); + } +#endif return FALSE; case WM_SETFOCUS: @@ -8203,7 +8500,7 @@ Enables icsEnables[] = { { IDM_MachineWhite, MF_BYCOMMAND|MF_GRAYED }, { IDM_MachineBlack, MF_BYCOMMAND|MF_GRAYED }, { IDM_TwoMachines, MF_BYCOMMAND|MF_GRAYED }, - { IDM_AnalysisMode, MF_BYCOMMAND|MF_GRAYED }, + { IDM_AnalysisMode, MF_BYCOMMAND|MF_ENABLED }, { IDM_AnalyzeFile, MF_BYCOMMAND|MF_GRAYED }, { IDM_TimeControl, MF_BYCOMMAND|MF_GRAYED }, { IDM_MoveNow, MF_BYCOMMAND|MF_GRAYED }, @@ -8398,6 +8695,17 @@ ModeHighlight() } prevChecked = nowChecked; + + /* [DM] icsEngineAnalyze - Do a sceure check too */ + if (appData.icsActive) { + if (appData.icsEngineAnalyze) { + (void) CheckMenuItem(GetMenu(hwndMain), IDM_AnalysisMode, + MF_BYCOMMAND|MF_CHECKED); + } else { + (void) CheckMenuItem(GetMenu(hwndMain), IDM_AnalysisMode, + MF_BYCOMMAND|MF_UNCHECKED); + } + } } VOID @@ -8410,6 +8718,9 @@ SetICSMode() #ifdef ZIPPY if (appData.zippyPlay) { SetMenuEnables(hmenu, zippyEnables); + if (!appData.noChessProgram) /* [DM] icsEngineAnalyze */ + (void) EnableMenuItem(GetMenu(hwndMain), IDM_AnalysisMode, + MF_BYCOMMAND|MF_ENABLED); } #endif } @@ -9144,11 +9455,13 @@ void DisplayWhiteClock(long timeRemaining, int highlight) { HDC hdc; - hdc = GetDC(hwndMain); char *flag = whiteFlag && gameMode == TwoMachinesPlay ? "(!)" : ""; + if(appData.noGUI) return; + hdc = GetDC(hwndMain); if (!IsIconic(hwndMain)) { - DisplayAClock(hdc, timeRemaining, highlight, flipClock ? &blackRect : &whiteRect, "White", flag); + DisplayAClock(hdc, timeRemaining, highlight, + (logoHeight > 0 ? flipView: flipClock) ? &blackRect : &whiteRect, "White", flag); } if (highlight && iconCurrent == iconBlack) { iconCurrent = iconWhite; @@ -9168,9 +9481,11 @@ DisplayBlackClock(long timeRemaining, int highlight) HDC hdc; char *flag = blackFlag && gameMode == TwoMachinesPlay ? "(!)" : ""; + if(appData.noGUI) return; hdc = GetDC(hwndMain); if (!IsIconic(hwndMain)) { - DisplayAClock(hdc, timeRemaining, highlight, flipClock ? &whiteRect : &blackRect, "Black", flag); + DisplayAClock(hdc, timeRemaining, highlight, + (logoHeight > 0 ? flipView: flipClock) ? &whiteRect : &blackRect, "Black", flag); } if (highlight && iconCurrent == iconWhite) { iconCurrent = iconBlack; @@ -9261,6 +9576,23 @@ CancelDelayedEvent() } } +DWORD GetWin32Priority(int nice) +{ // [HGM] nice: translate Unix nice() value to indows priority class. (Code stolen from Polyglot 1.4w11) +/* +REALTIME_PRIORITY_CLASS 0x00000100 +HIGH_PRIORITY_CLASS 0x00000080 +ABOVE_NORMAL_PRIORITY_CLASS 0x00008000 +NORMAL_PRIORITY_CLASS 0x00000020 +BELOW_NORMAL_PRIORITY_CLASS 0x00004000 +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; +} + /* Start a child process running the given program. The process's standard output can be read from "from", and its standard input can be written to "to". @@ -9376,6 +9708,11 @@ StartChildProcess(char *cmdLine, char *dir, ProcRef *pr) return err; } + if (appData.niceEngines){ // [HGM] nice: adjust engine proc priority + if(appData.debugMode) fprintf(debugFP, "nice engine proc to %d\n", appData.niceEngines); + SetPriorityClass(piProcInfo.hProcess, GetWin32Priority(appData.niceEngines)); + } + /* Close the handles we don't need in the parent */ CloseHandle(piProcInfo.hThread); CloseHandle(hChildStdinRd); @@ -10060,6 +10397,11 @@ AnalysisDialog(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) case WM_COMMAND: /* message: received a command */ switch (LOWORD(wParam)) { case IDCANCEL: + if (appData.icsActive && appData.icsEngineAnalyze) { /* [DM] icsEngineAnalyze */ + ExitAnalyzeMode(); + ModeHighlight(); + return TRUE; + } EditGameEvent(); return TRUE; default: