Allow WinBoard to use bitmaps with alpha channel
[xboard.git] / winboard / winboard.c
index 2301293..293b643 100644 (file)
  *------------------------------------------------------------------------\r
  ** See the file ChangeLog for a revision history.  */\r
 \r
+#ifndef WINVER\r
+#define WINVER 0x0500\r
+#endif\r
+\r
 #include "config.h"\r
 \r
 #include <windows.h>\r
@@ -2193,7 +2197,7 @@ void CreatePiecesFromFont()
 HBITMAP\r
 DoLoadBitmap(HINSTANCE hinst, char *piece, int squareSize, char *suffix)\r
 {\r
-  char name[128], buf[MSG_SIZ];\r
+  char name[128], buf[MSG_SIZ], *ids = "pnbrqfeicwmohajgdvlsukaacvdklnwpwnwlwswolfgnuzebracameltowersword", *p;\r
 \r
     snprintf(name, sizeof(name)/sizeof(name[0]), "%s%d%s", piece, squareSize, suffix);\r
   if(appData.pieceDirectory[0]) {\r
@@ -2201,6 +2205,30 @@ DoLoadBitmap(HINSTANCE hinst, char *piece, int squareSize, char *suffix)
     snprintf(buf, MSG_SIZ, "%s\\%s.bmp", appData.pieceDirectory, name);\r
     res = LoadImage( 0, buf, IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE );\r
     if(res) return res;\r
+    p = strstr(ids, piece);\r
+    if(p) { // if we could reconstruct canonical piece number, try the pieceNNN_ format before falling back on built-ins\r
+      int n = p - ids;\r
+      switch(n) {\r
+       case 21: n = WhiteKing; break;\r
+       case 22: n = WhiteAngel; break;\r
+       case 24: n = WhiteSilver; break;\r
+       case 26: n = WhiteDragon; break;\r
+       case 28: n = WhiteLion; break;\r
+       case 30: n = WhiteTokin; break;\r
+       case 32: n = WhitePKnight; break;\r
+       case 34: n = WhitePLance; break;\r
+       case 36: n = WhitePSilver; break;\r
+       case 38: n = WhiteWolf; break;\r
+       case 42: n = WhiteGnu; break;\r
+       case 45: n = WhiteZebra; break;\r
+       case 50: n = WhiteCamel; break;\r
+       case 55: n = WhiteTower; break;\r
+       case 60: n = WhiteSword; break;\r
+      }\r
+      snprintf(buf, MSG_SIZ, "%s\\piece%d_%d%s.bmp", appData.pieceDirectory, n, squareSize, suffix);\r
+      res = LoadImage( 0, buf, IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE );\r
+      if(res) return res;\r
+    }\r
   }\r
   if (gameInfo.event &&\r
       strcmp(gameInfo.event, "Easter Egg Hunt") == 0 &&\r
@@ -2727,6 +2755,15 @@ InitDrawingSizes(BoardSize boardSize, int flags)
     pieceBitmap[0][WhiteZebra] = DoLoadBitmap(hInst, "zebra", squareSize, "s");\r
     pieceBitmap[1][WhiteZebra] = DoLoadBitmap(hInst, "zebra", squareSize, "o");\r
     pieceBitmap[2][WhiteZebra] = DoLoadBitmap(hInst, "n", squareSize, "w");\r
+    pieceBitmap[0][WhiteTower] = DoLoadBitmap(hInst, "tower", squareSize, "s");\r
+    pieceBitmap[1][WhiteTower] = DoLoadBitmap(hInst, "tower", squareSize, "o");\r
+    pieceBitmap[2][WhiteTower] = DoLoadBitmap(hInst, "tower", squareSize, "w");\r
+    pieceBitmap[0][WhiteSword] = DoLoadBitmap(hInst, "sword", squareSize, "s");\r
+    pieceBitmap[1][WhiteSword] = DoLoadBitmap(hInst, "sword", squareSize, "o");\r
+    pieceBitmap[2][WhiteSword] = DoLoadBitmap(hInst, "sword", squareSize, "w");\r
+    pieceBitmap[0][WhiteGnu] = DoLoadBitmap(hInst, "gnu", squareSize, "s");\r
+    pieceBitmap[1][WhiteGnu] = DoLoadBitmap(hInst, "gnu", squareSize, "o");\r
+    pieceBitmap[2][WhiteGnu] = DoLoadBitmap(hInst, "gnu", squareSize, "w");\r
 \r
     if(gameInfo.variant == VariantShogi && BOARD_HEIGHT != 7) { /* promoted Gold representations (but not in Tori!)*/\r
       pieceBitmap[0][WhiteCannon] = DoLoadBitmap(hInst, "wp", squareSize, "s");\r
@@ -2983,7 +3020,7 @@ VOID
 DrawPieceOnDC(HDC hdc, ChessSquare piece, int color, int sqcolor, int x, int y, HDC tmphdc)\r
 {\r
   HBITMAP oldBitmap;\r
-  HBRUSH oldBrush;\r
+  HBRUSH oldBrush = NULL;\r
   int tmpSize;\r
 \r
   if (appData.blindfold) return;\r
@@ -3042,6 +3079,20 @@ DrawPieceOnDC(HDC hdc, ChessSquare piece, int color, int sqcolor, int x, int y,
       y += squareSize - minorSize - 2;\r
       tmpSize = minorSize;\r
     }\r
+#if WINVER >= 0x0500\r
+    HBITMAP pbm = PieceBitmap(piece, color ? OUTLINE_PIECE : SOLID_PIECE);\r
+    BITMAP b;\r
+    GetObject(pbm, sizeof(BITMAP), &b);\r
+    if(b.bmBitsPixel == 32) { // for now this is a kludge to indicate bitmaps with alpha channel\r
+       BLENDFUNCTION bf;\r
+       bf.BlendOp = AC_SRC_OVER;\r
+       bf.BlendFlags = 0;\r
+       bf.SourceConstantAlpha = 0xFF;\r
+       bf.AlphaFormat = AC_SRC_ALPHA;\r
+       oldBitmap = SelectObject(tmphdc, pbm);\r
+       AlphaBlend(hdc, x, y, tmpSize, tmpSize, tmphdc, 0, 0, tmpSize, tmpSize, bf);\r
+    } else\r
+#endif\r
     if (color || appData.allWhite ) {\r
       oldBitmap = SelectObject(tmphdc, PieceBitmap(piece, WHITE_PIECE));\r
       if( color )\r
@@ -3078,7 +3129,7 @@ DrawPieceOnDC(HDC hdc, ChessSquare piece, int color, int sqcolor, int x, int y,
       else\r
         BitBlt(hdc, x, y, tmpSize, tmpSize, tmphdc, 0, 0, 0x00B8074A);\r
     }\r
-    SelectObject(hdc, oldBrush);\r
+    if(oldBrush) SelectObject(hdc, oldBrush);\r
     SelectObject(tmphdc, oldBitmap);\r
   }\r
 }\r
@@ -3756,6 +3807,7 @@ void DrawSeekClose()
 \r
 \r
 \r
+\r
 VOID\r
 HDCDrawPosition(HDC hdc, BOOLEAN repaint, Board board)\r
 {\r
@@ -4179,6 +4231,7 @@ HDCDrawPosition(HDC hdc, BOOLEAN repaint, Board board)
        if(fac)\r
        for(i=0; i<16; i++) fputDW(diagFile, color[i]);\r
        // write bitmap data\r
+\r
        for(i=0; i<wb*(b.bmHeight - boardRect.top + OUTER_MARGIN); i++) \r
                fputc(pData[i], diagFile);\r
        free(pData);\r
@@ -6274,6 +6327,7 @@ InitComboStringsFromOption(HANDLE hwndCombo, char *str)
   }\r
 \r
 \r
+\r
   SendMessage(hwndCombo, CB_RESETCONTENT, 0, 0);\r
 \r
   for (;;) {\r